import 'codeceptjs'; import { Helper } from 'codeceptjs'; import * as fs from "fs"; import * as fs1 from "fs"; import { isNullOrUndefined } from 'util'; import { logger } from '../Logger/logger'; import { N } from "./N"; const config = require('codeceptjs').config.get(); import * as http from "http"; import { DOMParser } from "xmldom"; const { I } = inject(); let helper: any; export let webDriver = "WebDriver"; export let puppeteer = "Puppeteer"; // let runAutoheal = process.env.RUN_AUTOHEAL; if(config.helpers.WebDriver) helper = webDriver; else if(config.helpers.Puppeteer) helper = puppeteer export class z extends Helper { // static uiElements: Map = new Map(); static timeout = 0; static cb = () => { return new Promise((resolve, reject) => { reject(); }); }; /** * Scrolls element into viewport, waits for that element to become visible & clickable, then performs click action. * Throws error if any of the action fails in two attempts. * The second parameter is a context (CSS or XPath locator) to narrow the search. * ```js * // simple link * z.click('Logout'); * // button of form * z.click('Submit'); * // CSS button * z.click('#form input[type=submit]'); * // XPath * z.click('//form/*[@type=submit]'); * // link in context * z.click('Logout', '#nav'); * // using strict locator * z.click({css: 'nav a.login'}); * ``` * @param {string} locator CSS|XPath|strict locator. * @param {string} context (optional, null by default) element to search in CSS|XPath|Strict locator. */ static async click(locators: string, context?: string) { // const browser = this.prototype.helpers['WebDriver']; const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of click") // logger.info("Inside try block of click"); await I.wait(0); await allure.createStep(`z click "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); if (process.env.BROWSER === "internet explorer") { action = "executeScript"; await browser.executeScript(function (locator: string) { (document).evaluate(locator, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.click(); }, locator); } else { action = "waitForClickable"; await browser.waitForClickable(locator, N.globalTimeout()); // action = "click"; // await browser.click(locator); // await allure.createStep(`z click "${locator}"`, async()=>{ action = "click"; await browser.click(locator); // }); } } else { if (!isNullOrUndefined(context)) { if (!(process.env.BROWSER === "internet explorer")) { action = "click"; await browser.click(locator); } else { let xpath = "//*[contains(text(),'" + locator + "') or contains(@aria-label,'" + locator + "')]"; action = "executeScript"; await browser.executeScript(function (locator: string) { (document).evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.click(); }, xpath); } } else { if (!(process.env.BROWSER === "internet explorer")) { action = "click"; await browser.click(locator); } else { let xpath = "//*[contains(text(),'" + locator + "') or contains(@aria-label,'" + locator + "')]"; action = "executeScript"; await browser.executeScript(function (locator: string) { (document).evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.click(); }, xpath); } } } }); // allure.createStep("z click " + locator); } catch (error) { logger.info("Inside catch block of click"); locator = await this.getElements(locators) try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z click "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }) action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); if (process.env.BROWSER === "internet explorer") { action = "executeScript"; await browser.executeScript(function (locator: string) { (document).evaluate(locator, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.click(); }, locator); } else { action = "waitForClickable"; await browser.waitForClickable(locator, N.globalTimeout()); // action = "click"; // await browser.click(locator); // await allure.createStep(`z click "${locator}"`, async()=>{ action = "click"; await browser.click(locator); // }); } } else { if (!isNullOrUndefined(context)) { if (!(process.env.BROWSER === "internet explorer")) { action = "click"; await browser.click(locator); } else { let xpath = "//*[contains(text(),'" + locator + "') or contains(@aria-label,'" + locator + "')]"; action = "executeScript"; await browser.executeScript(function (locator: string) { (document).evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.click(); }, xpath); } } else { if (!(process.env.BROWSER === "internet explorer")) { action = "click"; await browser.click(locator); } else { let xpath = "//*[contains(text(),'" + locator + "') or contains(@aria-label,'" + locator + "')]"; action = "executeScript"; await browser.executeScript(function (locator: string) { (document).evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.click(); }, xpath); } } } }); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators, context]; throw new Error("ERROR" + error + "\n" + locator); } } } /** * Scrolls element into viewport, waits for that element to become visible & enabled, then clears field value. * Throws error if any of the action fails in two attempts. * ```js * z.clearField('Email'); * z.clearField('user[email]'); * z.clearField('#email'); * ``` * @param {string} locator CSS|XPath|strict locator. */ static async clearField(locators: string, setIWait0 = true) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of clearField"); if (setIWait0) { await I.wait(0); } await allure.createStep(`z clear field "${locator}`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "waitForEnabled"; await browser.waitForEnabled(locator, N.globalTimeout()); action = "click"; await browser.click(locator); action = "clearField"; await browser.clearField(locator); } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "click"; await browser.click(locator); action = "clearField"; await browser.clearField(locator); } }); //allure.createStep("z clear field " + locator); } catch (error) { logger.info("Inside catch block of clearField"); locator = await this.getElements(locators) try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z clear field "${locator}`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "waitForEnabled"; await browser.waitForEnabled(locator, N.globalTimeout()); action = "click"; await browser.click(locator); action = "clearField"; await browser.clearField(locator); } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "click"; await browser.click(locator); action = "clearField"; await browser.clearField(locator); } }); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators]; throw new Error("clearField : Error while clearing field value located by element : " + locator); } } } /** * Waits for element to be visible, Clears element value & fills given value. * Throws error if any of the action fails in two attempts. * ```js * // by label * z.fillField('Email', 'hello@world.com'); * // by name * z.fillField('password', secret('123456')); * // by CSS * z.fillField('form#login input[name=username]', 'John'); * // or by strict locator * z.fillField({css: 'form#login input[name=username]'} 'John'); * ``` * @param {string} locator CSS|XPath|strict locator. * @param {string} value */ static async fillField(locators: string, value: any) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) // await I.wait(0); try { logger.info("Inside try block of fillField"); await I.wait(0); await allure.createStep(`z fill field "${locator}, "${value}`, async () => { action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "clearField"; await this.clearField(locator, false); action = "fillField"; await browser.fillField(locator, value); }); } catch (error) { logger.info("Inside catch block of fillField"); locator = await this.getElements(locators) try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z fill field "${locator}, "${value}`, async () => { action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "clearField"; await this.clearField(locator, false); action = "fillField"; await browser.fillField(locator, value); }); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators, value]; throw new Error("ERROR" + error + "\n" + locator); } } } /** * Checks for the visibility of text, if optional context parameter given then searches for the visibility of text on the locator element. * Throws error if any of the action fails in two attempts. * ```js * z.see('Welcome'); // text welcome on a page * z.see('Welcome', '.content'); // text inside .content div * z.see('Register', {css: 'form.register'}); // use strict locator * ``` * @param {string} text * @param {string} context optional, element located by CSS|Xpath|strict locator in which to search for text. */ static async see(text: any, context?: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; try { logger.info("Inside try block of see"); await I.wait(0); if (isNullOrUndefined(context)) { action = "see"; await allure.createStep(`z see "${text}"`, async () => { action = "see"; await browser.wait(2); await browser.see(text); }); } else { action = "waitForVisible"; await browser.waitForVisible(context, N.globalTimeout()) // action = "see"; // await browser.see(text, context); await allure.createStep(`z see "${text}", "${context}"`, async () => { action = "see"; await browser.see(text, context); }); } // allure.createStep("z see " + text); } catch (error) { logger.info("Inside catch block of see"); try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } if (isNullOrUndefined(context)) { action = "see"; await allure.createStep(`z see "${text}"`, async () => { action = "see"; await browser.wait(2); await browser.see(text); }); } else { await allure.createStep(`z see "${text}", "${context}"`, async () => { action = "waitForVisible"; await browser.waitForVisible(context, N.globalTimeout()) action = "see"; await browser.see(text, context); }); } await this.generateLog(timestamp, error); } catch (error) { // allure.createStep("z " + action + " " + text + ", " + N.globalTimeout(), this.cb) N.stepName = action; N.stepArgs = [text, context]; throw new Error("ERROR" + error + "\n" + text); } } } /** * Checks the visibilty of an element. * Throws error if any of the action fails in two attempts. * ```js * z.seeElement('#modal'); * ``` * @param {string} locator CSS|XPath|strict locator. */ static async seeElement(locators: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of seeElement"); await I.wait(0); await allure.createStep(`z seeElement "${locator}"`, async () => { action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "seeElement"; await browser.seeElement(locator); }); // allure.createStep("z seeElement " + locator); } catch (error) { logger.info("Inside catch block of seeElement"); try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z seeElement "${locator}"`, async () => { action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "seeElement"; await browser.seeElement(locator); }); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators]; throw new Error("ERROR" + error + "\n" + locator); } } } /** * Opens a webpage in browser with given url. * ```js * z.amOnPage('/'); // opens main page of website * z.amOnPage('https://github.com'); // opens github * z.amOnPage('/login'); // opens a login page * ``` * @param {string} url */ static async amOnPage(url: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); await I.wait(0); await allure.createStep(`z am On Page "${url}"`, async () => { try { await browser.amOnPage(url); await allure.createStep(`z am On Page "${url}"`); } catch (error) { if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } } }); } /** * Asserts that two values are equal. If they are not,an assertion error is thrown. * ```js * I.assertEqual(expected,actual) * ``` * @param {any} expected * @param {any} actual */ static async assertEqual(expected: any, actual: any) { await I.assertEqual(expected, actual); } /** * Returns all window handles. Useful for referencing a specific handle when calling I.switchToWindow(handle) * ```js * const windows = await I.grabAllWindowHandles(); * ``` * @returns {Array} windows */ static async grabAllWindowHandles(): Promise { let windows: any; if(helper === webDriver) { const browser = this.prototype.helpers['WebDriver']; let allure: any = codeceptjs.container.plugins('allure'); try { await I.wait(0); await allure.createStep(`z grab all window Handles`, async () => { windows = await browser.grabAllWindowHandles(); }); // allure.createStep("z grab all window Handles " + windows); } catch (error) { if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "grabAllWindowHandles"; N.stepArgs = []; // allure.createStep("z grab all window Handles ", this.cb()); throw new Error("ERROR" + error + "\n"); } // return windows; } else if(helper === puppeteer) { windows = new Array(); const browser = this.prototype.helpers["Puppeteer"].browser; let pageArr = await browser.pages(); for(let i = 0; i < pageArr.length; i++) { windows.push(pageArr[i]["_target"]["_targetId"]); } // return windows; } return windows; } /** * Returns current window handle * ```js * const window = await z.grabCurrentWindowHandle(); * ``` * @returns {any} window */ static async grabCurrentWindowHandle(): Promise { let window = ''; if(helper === webDriver) { const browser = this.prototype.helpers['WebDriver']; let allure: any = codeceptjs.container.plugins('allure'); try { await I.wait(0); await allure.createStep(`z grab currenct window Handle"`, async () => { window = await browser.grabCurrentWindowHandle(); }); // allure.createStep("z grab currenct window Handle " + window); } catch (error) { if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "grabCurrentWindowHandle"; N.stepArgs = []; // allure.createStep("z grab currenct window Handle ", this.cb()); throw new Error("ERROR" + error + "\n"); } // return window; } else if(helper === puppeteer) { const helper = this.prototype.helpers["Puppeteer"]; window = helper.page._target._targetId; // return window; } return window; } /** * Grabs the number of visible elements * ```js * let numOfElements = await z.grabNumberOfVisibleElements('p'); * ``` * @param {string} locator CSS|XPath|strict locator. * @returns {any} totalElements */ static async grabNumberOfVisibleElements(locators: string): Promise { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let locator = ''; let totalElements = 0; locator = await this.getElements(locators) try { await I.wait(0); await allure.createStep(`z grab number of visible elements "${locator}"`, async () => { totalElements = await browser.grabNumberOfVisibleElements(locator); }); //allure.createStep("z grab number of visible elements " + locator); } catch (error) { if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } throw new Error("grabNumberOfVisibleElements: Error while grabbing the number of visible elements located by " + locator + "\n"); } return totalElements; } /** * Open new tab and switch to it. * ```js * z.openNewTab(); * ``` */ static async openNewTab() { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { await I.wait(0); await allure.createStep("z open new tab ", async () => { await browser.openNewTab(); }); } catch (error) { if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "openNewTab"; N.stepArgs = []; throw new Error("ERROR" + error + "\n"); } } /** * Presses a key or a key in combination with modifier keys in the browser (on a focused element). * ```js * z.pressKey('Backspace'); * ``` * * To press a key in combination with modifier keys, pass the sequence as an array. All modifier keys (`'Alt'`, `'Control'`, `'Meta'`, `'Shift'`) will be released afterwards. * * ```js * z.pressKey(['Control', 'Z']); * ``` * * For specifying operation modifier key based on operating system it is suggested to use `'CommandOrControl'`. * This will press `'Command'` (also known as `'Meta'`) on macOS machines and `'Control'` on non-macOS machines. * * ```js * z.pressKey(['CommandOrControl', 'Z']); * ``` * * Some of the supported key names are: * - `'AltLeft'` or `'Alt'` * - `'AltRight'` * - `'ArrowDown'` * - `'ArrowLeft'` * - `'ArrowRight'` * - `'ArrowUp'` * - `'Backspace'` * - `'Clear'` * - `'ControlLeft'` or `'Control'` * - `'ControlRight'` * - `'Command'` * - `'CommandOrControl'` * - `'Delete'` * - `'End'` * - `'Enter'` * - `'Escape'` * - `'F1'` to `'F12'` * - `'Home'` * - `'Insert'` * - `'MetaLeft'` or `'Meta'` * - `'MetaRight'` * - `'Numpad0'` to `'Numpad9'` * - `'NumpadAdd'` * - `'NumpadDecimal'` * - `'NumpadDivide'` * - `'NumpadMultiply'` * - `'NumpadSubtract'` * - `'PageDown'` * - `'PageUp'` * - `'Pause'` * - `'Return'` * - `'ShiftLeft'` or `'Shift'` * - `'ShiftRight'` * - `'Space'` * - `'Tab'` * @param {string|Array} key */ static async pressKey(key: string | string[]) { let allure: any = codeceptjs.container.plugins('allure'); const browser = await this.getHelper(); try { await I.wait(0); await allure.createStep(`z pressKey "${key}`, async () => { await browser.pressKey(key); }); } catch (error) { if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "pressKey"; N.stepArgs = [key]; throw new Error("ERROR" + error + "\n" + key); } } /** * Reload the current page. * ```js * z.refreshPage(); * ``` */ static async refreshPage() { let allure: any = codeceptjs.container.plugins('allure'); const browser = await this.getHelper(); try { await I.wait(0); await allure.createStep(`z refresh page`, async () => { await browser.refreshPage(); }); } catch (error) { if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "refreshPage"; N.stepArgs = []; throw new Error("ERROR" + error + "\n"); } } /** * Saves a screenshot to ouput folder (set in codecept.json or codecept.conf.js). * Filename is relative to output folder. Optionally resize the window to the full available page scrollHeight and scrollWidth * to capture the entire page by passing true in as the second argument. * ```js * z.saveScreenshot('debug.png'); * z.saveScreenshot('debug.png', true) //resizes to available scrollHeight and scrollWidth before taking screenshot * ``` * @param {string} fileName * @param {boolean} fullPage optional */ static async saveScreenshot(fileName: string, fullPage?: boolean) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); await I.wait(0); if (isNullOrUndefined(fullPage)) { await allure.createStep(`z save screenshot "${fileName}`, async () => { await browser.saveScreenshot(fileName); }); } else { await allure.createStep(`z save screenshot "${fileName}", ${fullPage}`, async () => { await browser.saveScreenshot(fileName, fullPage); }); } } /** * Switches frame or in case of null locator reverts to parent. * ```js * z.switchTo('iframe'); // switch to first iframe * z.switchTo(); // switch back to main page * ``` * @param {string} locator optional, CSS|XPath|strict locator. */ static async switchTo(locator?: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { await I.wait(0); if (!isNullOrUndefined(locator)) { await allure.createStep(`z switch to "${locator}`, async () => { await browser.switchTo(locator); }); } else { await allure.createStep("z switch to ", async () => { await browser.switchTo(); }); } } catch (error) { if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "switchTo"; N.stepArgs = [locator]; throw new Error("ERROR" + error + "\n" + locator); } } /** * Switch focus to a particular tab by its number. It waits tabs loading and then switch tab. * ```js * z.switchToNextTab(); * z.switchToNextTab(2); * ``` * @param {number} tabNum optional, number of tabs to switch forward, default: 1. * @param {number} timeout optional, time in seconds to wait. */ static async switchToNextTab(tabNum?: number, timeout?: number) { let allure: any = codeceptjs.container.plugins('allure'); const browser = await this.getHelper(); try { await I.wait(0); await allure.createStep(`z switch to next tab "${tabNum}"`); await browser.switchToNextTab(tabNum, timeout); } catch (error) { if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "switchToNextTab"; N.stepArgs = [tabNum, timeout]; throw new Error("ERROR" + error + "\n"); } } /** * Switch to the window with a specified handle. * ```js * const windows = await z.grabAllWindowHandles(); * // do something * await z.switchToWindow( windows[0] ); * * const window = await z.grabCurrentWindowHandle(); * // do something * await z.switchToWindow( window ); * ``` * @param {string} window */ static async switchToWindow(window?: any) { if(helper === webDriver) { let allure: any = codeceptjs.container.plugins('allure'); const browser = this.prototype.helpers['WebDriver']; try { await I.wait(0); if (isNullOrUndefined(window)) { await allure.createStep("z switch to window ", async () => { await browser.switchToWindow(); }); } else { await allure.createStep(`z switch to window "${window}"`, async () => { await browser.switchToWindow(window); }); } } catch (error) { if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "switchToWindow"; N.stepArgs = [window]; throw new Error("ERROR" + error + "\n"); } } else if(helper === puppeteer) { const helper = this.prototype.helpers["Puppeteer"]; let currentWindowId = helper.page._target._targetId; const browser = this.prototype.helpers["Puppeteer"].browser; let pageArr: any[] = await browser.pages(); let windowArr: string[] = new Array(); for (const page of pageArr) { windowArr.push(page["_target"]["_targetId"]); } let currentWindowIndex = windowArr.indexOf(currentWindowId); let targetWindowIndex = windowArr.indexOf(window); if(currentWindowId < targetWindowIndex) { await helper.switchToNextTab(targetWindowIndex); } else if(currentWindowId > targetWindowIndex) { await helper.switchToPreviousTab(currentWindowIndex - targetWindowIndex); } } } /** * Pauses execution for a number of seconds. * ```js * z.wait(2); // wait 2 secs * ``` * @param {number} timeout */ static async wait(timeout: any) { let allure: any = codeceptjs.container.plugins('allure'); const browser = await this.getHelper(); try { await allure.createStep(`z wait "${timeout}"`, async () => { await browser.wait(timeout); }); } catch (error) { if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "wait"; N.stepArgs = [timeout]; throw new Error("wait : Error while waiting: "); } } /** * Waits for the visibility of element & for the specified value to be in value attribute. * ```js * z.waitForValue('//input', "GoodValue"); * ``` * @param {string} locator input field locator. * @param {string} value * @param {number} timeout optional, default timeout is value mentioned against key "waitForTimeout" */ static async waitForValue(locators: string, value: string, timeout?: number) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of waitForValue"); await I.wait(0); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); if (isNullOrUndefined(timeout)) { await allure.createStep(`z wait For Value "${locator}", "${value}"`, async () => { action = "waitForValue"; await browser.waitForValue(locator, value, N.globalTimeout()); }); } else { await allure.createStep(`z wait For Value "${locator}", "${value}", ${timeout}`, async () => { action = "waitForValue"; await browser.waitForValue(locator, value, timeout); }); } } catch (error) { logger.info("Inside catch block of waitForValue"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); // if (timeout) { // allure.createStep("z wait for value " + locator + " " + timeout, this.cb); // } // else { // allure.createStep("z wait for value " + locator + ", " + N.globalTimeout(), this.cb); // } N.stepName = "waitForValue"; N.stepArgs = [locators, value, timeout]; throw new Error("waitForValue : Error while waiting for value in element located by : " + locator); } } /** * Waits for the visibility of element. * ```js * z.waitForVisible('#popup'); * ``` * @param {string} locator CSS|XPath|strict locator. * @param {number} timeout optional, default timeout is value mentioned against key "waitForTimeout" */ static async waitForVisible(locators: string, timeout?: number) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of waitForVisible " + locator); await I.wait(0); if (!isNullOrUndefined(timeout)) { await allure.createStep("z wait for visible " + locator + " " + timeout, async () => { await browser.waitForVisible(locator, timeout); }); } else { await allure.createStep("z wait for visible " + locator, async () => { await browser.waitForVisible(locator, N.globalTimeout()); }); } } catch (error) { logger.info("Inside catch block of waitForVisible"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); // if (timeout) { // allure.createStep("z wait for visible " + locator + " " + timeout, this.cb); // } // else { // allure.createStep("z wait for visible " + locator + ", " + N.globalTimeout(), this.cb); // } N.stepName = "waitForVisible"; N.stepArgs = [locators, timeout]; throw new Error("ERROR" + error + "\n" + locator); } } /** * Waits for a text to appear. * Element can be located by CSS or XPath. Narrow down search results by providing context. * ```js * z.waitForText('Thank you, form has been submitted'); * z.waitForText('Thank you, form has been submitted', 5, '#modal'); * ``` * @param {string} text * @param {number} timeout optional, default timeout is value mentioned against key "waitForTimeout" * @param {string} locator optional, CSS|XPath|strict locator. */ static async waitForText(text: string, timeout?: number, locator?: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; try { logger.info("Inside try block of waitForText"); await I.wait(0); await allure.createStep(`z wait for text "${text}"`, async () => { if (!isNullOrUndefined(locator) && isNullOrUndefined(timeout)) { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForText"; await browser.waitForText(text, N.globalTimeout(), locator); } else if (!isNullOrUndefined(timeout) && isNullOrUndefined(locator)) { action = "waitForText"; await browser.waitForText(text, timeout); } else if (!isNullOrUndefined(timeout) && !isNullOrUndefined(locator)) { action = "scrollIntoView"; // await browser.scrollIntoView(locator, true); await this.scrollIntoViewWrapper(browser, locator, true); action = "waitForText"; await browser.waitForText(text, timeout, locator); } }); } catch (error) { logger.info("Inside catch block of waitForText"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); // if (timeout) { // allure.createStep("z wait for text " + locator + " " + timeout, this.cb); // } // else { // allure.createStep("z wait for text " + locator + ", " + N.globalTimeout(), this.cb); // } N.stepName = "waitForText"; N.stepArgs = [text, timeout, locator]; throw new Error("waitForText : Error while waiting for text : " + text); } } /** * Waits for an element to be removed or become invisible on a page. * Element can be located by CSS or XPath. * ```js * z.waitForInvisible('#popup'); * ``` * @param {string} locator CSS|XPath|strict locator. * @param {number} timeout optional, default timeout is value mentioned against key "waitForTimeout" */ static async waitForInvisible(locators: string, timeout?: number) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let locator = ''; try { logger.info("Inside try block of waitForInvisible"); await I.wait(0); locator = await this.getActualXpath(locators) await allure.createStep(`z wait for invisible "${locator}"`, async () => { if (isNullOrUndefined(timeout)) { await browser.waitForInvisible(locator, N.globalTimeout()); // allure.createStep("z wait for invisible " + locator); } else { await browser.waitForInvisible(locator, timeout); // allure.createStep("z wait for invisible " + locator + ", " + timeout); } }); } catch (error) { logger.info("Inside catch block of waitForInvisible"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); if (timeout) { allure.createStep("z wait for invisible " + locator + " " + timeout, this.cb); } else { allure.createStep("z wait for invisible " + locator + ", " + N.globalTimeout(), this.cb); } N.stepName = "waitForInvisible"; N.stepArgs = [locators, timeout]; throw new Error("waitForInvisible : Error while waiting invisibility of element located by: " + locator); } } /** * Waits for an element to become enabled. * Element can be located by CSS or XPath. * ```js * z.waitForEnabled('#popup'); * ``` * @param {string} locator CSS|XPath|strict locator. * @param {number} timeout optional, default timeout is value mentioned against key "waitForTimeout" */ static async waitForEnabled(locators: string, timeout?: number) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of waitForEnabled"); await I.wait(0); await allure.createStep(`z wait for enabled "${locator}"`, async () => { if (isNullOrUndefined(timeout)) { await browser.waitForEnabled(locator, N.globalTimeout()); // allure.createStep("z wait for enabled " + locator); } else { await browser.waitForEnabled(locator, timeout); // allure.createStep("z wait for enabled " + locator + " " + timeout); } }); } catch (error) { logger.info("Inside catch block of waitForEnabled"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); // if (timeout) { // allure.createStep("z wait for Enabled " + locator + " " + timeout, this.cb); // } // else { // allure.createStep("z wait for Enabled " + locator + ", " + N.globalTimeout(), this.cb); // } N.stepName = "waitForEnabled"; N.stepArgs = [locators, timeout]; throw new Error("waitForEnabled : Error while waiting for element to be enabled located by: " + locator); } } /** * Waits for an element to be present on page. * Element can be located by CSS or XPath. * ```js * z.waitForElement('.btn.continue'); * z.waitForElement('.btn.continue', 5); // wait for 5 secs * ``` * @param {string} locator CSS|XPath|strict locator. * @param {number} timeout optional, default timeout is value mentioned against key "waitForTimeout" */ static async waitForElement(locators: string, timeout?: number) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of waitForElement"); await I.wait(0); await allure.createStep(`z wait for visible "${locator}"`, async () => { if (!isNullOrUndefined(timeout)) { await browser.waitForElement(locator, timeout); } else { await browser.waitForElement(locator, N.globalTimeout()); } // allure.createStep("z wait for visible " + locator); }); } catch (error) { logger.info("Inside catch block of waitForElement"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); // if (timeout) { // allure.createStep("z wait for Element " + locator + " " + timeout, this.cb); // } // else { // allure.createStep("z wait for Element " + locator + ", " + N.globalTimeout(), this.cb); // } N.stepName = "waitForElement"; N.stepArgs = [locators, timeout]; throw new Error("waitForElement : Error while waiting for element to be present located by: " + locator); } } /** * Waits for an element to be clickable. * Element can be located by CSS or XPath. * ```js * z.waitForClickable('.btn.continue'); * z.waitForClickable('.btn.continue', 5); // wait for 5 secs * ``` * @param {string} locator CSS|XPath|strict locator. * @param {number} timeout optional, default timeout is value mentioned against key "waitForTimeout" */ static async waitForClickable(locators: string, timeout?: number) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let locator = ''; locator = await this.getElements(locators); try { logger.info("Inside try block of waitForClickable"); await I.wait(0); if (isNullOrUndefined(timeout)) { allure.createStep(`z wait for clickable "${locator}"`, async () => { await browser.waitForClickable(locator, N.globalTimeout()); }); } else { allure.createStep(`z wait for clickable "${locator}", ${timeout}`, async () => { await browser.waitForClickable(locator, N.globalTimeout()); }); } } catch (error) { logger.info("Inside catch block of waitForClickable"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); // if (timeout) { // allure.createStep("z wait for clickable " + locator + " " + timeout, this.cb); // } // else { // allure.createStep("z wait for clickable " + locator + ", " + N.globalTimeout(), this.cb); // } N.stepName = "waitForClickable"; N.stepArgs = [locators, timeout]; throw new Error("waitForClickable : Error while waiting for element to be clickable located by: " + locator); } } /** * Waits for an element to be visible. * Element can be located by CSS or XPath. * ```js * z.attachFile('Avatar', 'data/avatar.jpg'); * z.attachFile('form input[name=avatar]', 'data/avatar.jpg'); * ``` * @param {string} locator label|name|CSS|XPath|strict locator. * @param {string} filepath local file path relative to codecept.json config file */ static async attachFile(locators: string, filepath: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of attachFile"); await I.wait(0); await allure.createStep(`z attach file "${locator}", filepath ${filepath}`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "attachFile"; await browser.attachFile(locator, filepath); } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "attachFile"; await browser.attachFile(locator, filepath); } // allure.createStep("z attach file " + locator + " filepath " + filepath); }); } catch (error) { logger.info("Inside catch block of attachFile"); try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z attach file "${locator}", filepath ${filepath}`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "attachFile"; await browser.attachFile(locator, filepath); } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "attachFile"; await browser.attachFile(locator, filepath); } // allure.createStep("z attach file " + locator + " filepath " + filepath); }); await this.generateLog(timestamp, error); } catch (error) { // allure.createStep("z " + action + " " + locator + " filepath " + filepath, this.cb); N.stepName = action; N.stepArgs = [locators, filepath]; throw new Error("attachFile : Error while uploading file to the element located by: " + locator); } } } /** * Switch focus to a particular tab by its number. It waits tabs loading and then switch tab. * ```js * z.switchToPreviousTab(); * z.switchToPreviousTab(2); * ``` * @param {number} tabNum optional, number of tabs to switch backward, default: 1. * @param {number} timeout optional, time in seconds to wait. */ static async switchToPreviousTab(tabNum?: number, timeout?: number) { let allure: any = codeceptjs.container.plugins('allure'); const browser = await this.getHelper(); try { await I.wait(0); await allure.createStep(`z switch to previous tab `, async () => { await browser.switchToPreviousTab(tabNum, timeout); }); } catch (error) { if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "switchToPreviousTab"; N.stepArgs = [tabNum, timeout]; throw new Error("switchToPreviousTab : Error while switch To Previous Tab: "); } } /** * Close current tab. * ```js * z.closeCurrentTab(); * ``` */ static async closeCurrentTab() { let allure: any = codeceptjs.container.plugins('allure'); const browser = await this.getHelper(); try { await I.wait(0); await allure.createStep("z close current tab ", async () => { await browser.closeCurrentTab(); }); } catch (error) { if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "closeCurrentTab"; N.stepArgs = []; throw new Error("closeCurrentTab : Error while closing Current Tab: "); } } /** * Close all tabs except for the current one. * ```js * z.closeOtherTabs(); * ``` */ static async closeOtherTabs() { let allure: any = codeceptjs.container.plugins('allure'); const browser = await this.getHelper(); try { await I.wait(0); await allure.createStep("z close other tabs ", async () => { await browser.closeOtherTabs(); }); } catch (error) { if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "closeOtherTabs"; N.stepArgs = []; throw new Error("closeOtherTabs : Error while closing other Tabs: "); } } /** * Scroll element into viewport. * ```js * z.scrollIntoView('#submit'); * z.scrollIntoView('#submit', { behavior: "smooth", block: "center", inline: "center" }); * z.scrollIntoView('#submit', true); * ``` * @param {string} locator CSS|XPath|strict locator. * @param {any} alignTop optional, or scrollIntoViewOptions (optional), * see https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView. */ static async scrollIntoView(locators: string, alignTop?: any) { if(helper === webDriver) { const browser = this.prototype.helpers['WebDriver']; let allure: any = codeceptjs.container.plugins('allure'); let locator = ''; locator = await this.getElements(locators); try { logger.info("Inside try block of scrollIntoView"); await I.wait(0); await allure.createStep(`z scroll into view "${locator}, ${alignTop}`, async () => { if (!isNullOrUndefined(alignTop)) { await browser.scrollIntoView(locator, alignTop); } else { await browser.scrollIntoView(locator); // allure.createStep("z scroll into view " + locator); } }); } catch (error) { logger.info("Inside catch block of scrollIntoView"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } // allure.createStep("z scroll into view " + locator, this.cb); N.stepName = "scrollIntoView"; N.stepArgs = [locator, alignTop]; throw new Error("scrollIntoView : Error while scroll into view element located by: " + locator); } } else if(helper === puppeteer) { if (!alignTop) { // await I.scrollIntoView(locator, alignTop); let arr = await this.getXYCoordinates(); await I.scrollTo(locators, arr[0], arr[1]); } else { // await I.scrollIntoView(locator); let arr = await this.getXYCoordinates(alignTop!); // console.log("coordinates fetched " + arr[0] + arr[1]); await I.scrollTo(locators, arr[0], arr[1]); } } } /** * Retrieves a text from an element located by CSS or XPath and returns it to test. * Resumes test execution, so should be used inside static async with await operator. * If multiple elements found returns an array of texts. * ```js * let pin = await z.grabTextFrom('#pin'); * ``` * @param {string} locator element located by CSS|XPath|strict locator. * @returns {string|string[]} text */ static async grabTextFrom(locators: string): Promise { let text: any = ""; const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of grabTextFrom"); await I.wait(0); await allure.createStep(`z grab text from "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "grabTextFrom"; text = await browser.grabTextFrom(locator); } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "grabTextFrom"; text = await browser.grabTextFrom(locator); } }); //allure.createStep("z grab text from " + locator); } catch (error) { logger.info("Inside catch block of grabTextFrom"); try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z grab text from "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "grabTextFrom"; text = await browser.grabTextFrom(locator); } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "grabTextFrom"; text = await browser.grabTextFrom(locator); } }); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators]; throw new Error("grabTextFrom : Error while fetching text from element located by: " + locator); } } return text; } /** * Retrieves an attribute from an element located by CSS or XPath and returns it to test. An array as a result will be returned if there are more than one matched element. * Resumes test execution, so should be used inside static async with await operator. * ```js * let hint = await z.grabAttributeFrom('#tooltip', 'title'); * ``` * @param {string} locator element located by CSS|XPath|strict locator. * @param {string} attribute attribute name. * @returns {string} text */ static async grabAttributeFrom(locators: string, attribute: string): Promise { let value: any = ""; const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of grabAttributeFrom"); await I.wait(0); await allure.createStep(`z grab attribute from "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "grabAttributeFrom"; value = await browser.grabAttributeFrom(locator, attribute); } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "grabAttributeFrom"; value = await browser.grabAttributeFrom(locator, attribute); } }); // allure.createStep("z grab attribute from " + locator); } catch (error) { logger.info("Inside catch block of grabAttributeFrom"); try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z grab attribute from "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "grabAttributeFrom"; value = await browser.grabAttributeFrom(locator, attribute); } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "grabAttributeFrom"; value = await browser.grabAttributeFrom(locator, attribute); } }); //allure.createStep("z grab attribute from " + locator); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators, attribute]; throw new Error("grabAttributeFrom : Error while fetching attribute '" + attribute + "' from element located by: " + locator); } } return value; } /** * Scrolls element into viewport, waits for that element to become visible & clickable. Also checks if element is already checked. * Then selects a checkbox or radio button. * * The second parameter is a context (CSS or XPath locator) to narrow the search. * ```js * z.checkOption('#agree'); * z.checkOption('I Agree to Terms and Conditions'); * z.checkOption('agree', '//form'); * ``` * @param {string} locator checkbox located by label | name | CSS | XPath | strict locator. * @param {string} context optional element located by CSS | XPath | strict locator. */ static async checkOption(locators: string, context?: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of checkOption"); await I.wait(0); await allure.createStep(`z check option "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "waitForClickable"; await browser.waitForClickable(locator, N.globalTimeout()); action = "dontSeeCheckboxIsChecked"; await browser.dontSeeCheckboxIsChecked(locator); } if (!isNullOrUndefined(context)) { action = "checkOption"; await browser.checkOption(locator, context); } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "checkOption"; await browser.checkOption(locator); } }); // allure.createStep("z check option " + locator); } catch (error) { logger.info("Inside catch block of checkOption"); try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z check option "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "waitForClickable"; await browser.waitForClickable(locator, N.globalTimeout()); action = "dontSeeCheckboxIsChecked"; await browser.dontSeeCheckboxIsChecked(locator); } if (!isNullOrUndefined(context)) { action = "checkOption"; await browser.checkOption(locator, context); } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "checkOption"; await browser.checkOption(locator); } }); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators, context]; throw new Error("checkOption : Error while selecting element located by: " + locator); } } } /** * Checks that a text is not present on a page, if optional context parameter given then searches for the invisibility of text on the locator element. * Use context parameter to narrow down the search. * Throws error if any of the action fails in two attempts. * ```js * z.dontSee('Login'); // assume we are already logged in. * z.dontSee('Login', '.nav'); // no login inside .nav element * ``` * @param {string} text which is not present. * @param {string} context optional, element located by CSS|Xpath|strict locator in which to search for text. */ static async dontSee(text: string, context?: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { logger.info("Inside try block of dontSee"); await I.wait(0); if (!isNullOrUndefined(context)) { await allure.createStep(`z dontSee "${text}, "${context}"`, async () => { await browser.dontSee(text, context); }); } else { await allure.createStep("z dontSee " + text, async () => { await browser.dontSee(text); }); } } catch (error) { logger.info("Inside catch block of dontSee"); try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } if (!isNullOrUndefined(context)) { await allure.createStep(`z dontSee "${text}, "${context}"`, async () => { await browser.dontSee(text, context); }); } else { await allure.createStep("z dontSee " + text, async () => { await browser.dontSee(text); }); } await this.generateLog(timestamp, error); } catch (error) { // allure.createStep("z dontSee " + text + " " + context, this.cb); N.stepName = "dontSee"; N.stepArgs = [text, context]; throw new Error("dontSee : Error while checking invisibility of element by: " + text); } } } /** * Checks that element is not visible (or in DOM) * Throws error if any of the action fails in two attempts. * ```js * z.seeElement('#modal'); * ``` * @param {string} locator CSS|XPath|strict locator. */ static async dontSeeElement(locators: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of dontSeeElement"); await I.wait(0); await allure.createStep("z dont see element " + locator, async () => { await browser.dontSeeElement(locator); }) } catch (error) { logger.info("Inside catch block of dontSeeElement"); try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep("z dont see element " + locator, async () => { await browser.dontSeeElement(locator); }) await this.generateLog(timestamp, error); } catch (error) { // allure.createStep("z dont see element " + locator, this.cb) N.stepName = "dontSeeElement"; N.stepArgs = [locators]; throw new Error("dontSeeElement : Error while checking invisibility of element by: " + locator); } } } /** * Scrolls element into viewport, waits for that element to become visible & clickable, then performs double click action. * Throws error if any of the action fails in two attempts. * The second parameter is a context (CSS or XPath locator) to narrow the search. * ```js * z.doubleClick('Edit'); * z.doubleClick('Edit', '.actions'); * z.doubleClick({css: 'button.accept'}); * z.doubleClick('.btn.edit'); * ``` * @param {string} locator CSS|XPath|strict locator. * @param {string} context (optional, null by default) element to search in CSS|XPath|Strict locator. */ static async doubleClick(locators: string, context?: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of doubleClick"); await I.wait(0); await allure.createStep(`z double click "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "waitForClickable"; await browser.waitForClickable(locator, N.globalTimeout()); } if (!isNullOrUndefined(context)) { action = "doubleClick"; await browser.doubleClick(locator, context); // allure.createStep("z double click " + locator + " " + context) } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "doubleClick"; await browser.doubleClick(locator); // allure.createStep("z double click " + locator); } }); } catch (error) { logger.info("Inside catch block of doubleClick"); try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z double click "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "waitForClickable"; await browser.waitForClickable(locator, N.globalTimeout()); } if (!isNullOrUndefined(context)) { action = "doubleClick"; await browser.doubleClick(locator, context); // allure.createStep("z double click " + locator + " " + context) } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "doubleClick"; await browser.doubleClick(locator); // allure.createStep("z double click " + locator); } }); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators, context]; throw new Error("doubleClick : Error while double clicking on element located by : " + locator); } } } /** * Scrolls element into viewport, waits for that element to become visible & clickable, then Drag an item to a destination element. * Throws error if any of the action fails in two attempts. * * ```js * z.dragAndDrop('#dragHandle', '#container'); * ``` * @param {string} srcLocator CSS|XPath|strict locator. * @param {string} destLocator CSS|XPath|Strict locator. */ static async dragAndDrop(srcLocator: string, destLocator: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; try { srcLocator = await this.getActualXpath(srcLocator); destLocator = await this.getActualXpath(destLocator); logger.info("Inside try block of dragAndDrop"); await I.wait(0); await allure.createStep(`z drag and drop "${srcLocator}" to "${destLocator}"`, async () => { if (srcLocator.startsWith("/") || srcLocator.startsWith(".") || srcLocator.startsWith("#") || srcLocator.startsWith("{")) { action = "waitForElement"; await browser.waitForElement(srcLocator); if (process.env.BROWSER === "internet explorer") { action = "scrollTo"; await browser.scrollTo(srcLocator); } else { action = "scrollIntoView"; // await browser.scrollIntoView(srcLocator, { behavior: "auto", block: "center", inline: "center" }); await this.scrollIntoViewWrapper(browser, srcLocator, { behavior: "auto", block: "center", inline: "center" }); } action = "waitForVisible"; await browser.waitForVisible(srcLocator); action = "waitForClickable"; await browser.waitForClickable(srcLocator); action = "waitForVisible"; await browser.waitForVisible(destLocator); action = "dragAndDrop"; await browser.dragAndDrop(srcLocator, destLocator); } else { if (process.env.BROWSER === "internet explorer") { action = "scrollTo"; await browser.scrollTo(srcLocator); } else { action = "scrollIntoView"; // await browser.scrollIntoView(srcLocator, { behavior: "auto", block: "center", inline: "center" }); await this.scrollIntoViewWrapper(browser, srcLocator, { behavior: "auto", block: "center", inline: "center" }); } action = "dragAndDrop"; await browser.dragAndDrop(srcLocator, destLocator); } }); // allure.createStep("z drag and drop " + srcLocator + " to " + destLocator); } catch (error) { logger.info("Inside catch block of dragAndDrop"); try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z drag and drop "${srcLocator}" to "${destLocator}"`, async () => { if (srcLocator.startsWith("/") || srcLocator.startsWith(".") || srcLocator.startsWith("#") || srcLocator.startsWith("{")) { action = "waitForElement"; await browser.waitForElement(srcLocator); if (process.env.BROWSER === "internet explorer") { action = "scrollTo"; await browser.scrollTo(srcLocator); } else { action = "scrollIntoView"; // await browser.scrollIntoView(srcLocator, { behavior: "auto", block: "center", inline: "center" }); await this.scrollIntoViewWrapper(browser, srcLocator, { behavior: "auto", block: "center", inline: "center" }); } action = "waitForVisible"; await browser.waitForVisible(srcLocator); action = "waitForClickable"; await browser.waitForClickable(srcLocator); action = "waitForVisible"; await browser.waitForVisible(destLocator); action = "dragAndDrop"; await browser.dragAndDrop(srcLocator, destLocator); } else { if (process.env.BROWSER === "internet explorer") { action = "scrollTo"; await browser.scrollTo(srcLocator); } else { action = "scrollIntoView"; // await browser.scrollIntoView(srcLocator, { behavior: "auto", block: "center", inline: "center" }); await this.scrollIntoViewWrapper(browser, srcLocator, { behavior: "auto", block: "center", inline: "center" }); } action = "dragAndDrop"; await browser.dragAndDrop(srcLocator, destLocator); } }); // allure.createStep("z drag and drop " + srcLocator + " to " + destLocator); await this.generateLog(timestamp, error); } catch (error) { //allure.createStep("z drag and drop " + srcLocator + " to " + destLocator + ", " + N.globalTimeout(), this.cb); N.stepName = "dragAndDrop"; N.stepArgs = [srcLocator, destLocator]; throw new Error("dragAndDrop : Error while performing drag and drop from element located by : " + srcLocator + " to " + destLocator); } } } /** * Executes sync script on a page. * Pass arguments to function as additional parameters. * Will return execution result to a test. * In this case you should use static async function and await to receive results. * * Example with jQuery DatePicker: * * ```js * // change date of jQuery DatePicker * z.executeScript(function() { * // now we are inside browser context * $('date').datetimepicker('setDate', new Date()); * }); * ``` * Can return values. Don't forget to use `await` to get them. * * ```js * let date = await z.executeScript(function(el) * // only basic types can be returned * return $(el).datetimepicker('getDate').tostring(); * } '#date'); // passing jquery selector * ``` * @param {string|function} fn function to be executed in browser context. * @param {...any} args to be passed to function. * */ static async executeScript(fn: any | ((...params: any[]) => any), ...args: any[]): Promise { let retunrtype = ''; if(helper === webDriver) { const browser = this.prototype.helpers['WebDriver']; let allure: any = codeceptjs.container.plugins('allure'); try { await I.wait(0); await allure.createStep("z execute script" + fn, async () => { retunrtype = await I.executeScript(fn, args); }); // return retunrtype; } catch (error) { if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "executeScript"; N.stepArgs = [fn, args]; throw new Error("executeScript : Error while executeScript "); } } else if(helper === puppeteer) { const helper = this.prototype.helpers["Puppeteer"]; retunrtype = await helper.page.evaluate(fn, args); // return retunrtype; } return retunrtype; } /** * Scrolls element into viewport, waits for that element to become visible & clickable, then selects an option in a drop-down select. * Throws error if any of the action fails in two attempts. * * ```js * z.selectOption('Choose Plan', 'Monthly'); // select by label * z.selectOption('subscription', 'Monthly'); // match option by text * z.selectOption('subscription', '0'); // or by value * z.selectOption('//form/select[@name=account]','Premium'); * z.selectOption('form select[name=account]', 'Premium'); * z.selectOption({css: 'form select[name=account]'} 'Premium'); * ``` * Provide an array for the second argument to select multiple options. * ```js * z.selectOption('Which OS do you use?', ['Android', 'iOS']); * ``` * @param {string} locator CSS|XPath|strict locator. * @param {string|string[]} option CSS|XPath|Strict locator. */ static async selectOption(locators: string, option: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of selectOption"); await I.wait(0); await allure.createStep(`z select option "${locator}", "${option}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "waitForClickable"; await browser.waitForClickable(locator, N.globalTimeout()); action = "selectOption"; await browser.selectOption(locator, option); } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "selectOption"; await browser.selectOption(locator, option); } }); // allure.createStep("z select option " + locator + option); } catch (error) { logger.info("Inside catch block of selectOption"); try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z select option "${locator}", "${option}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "waitForClickable"; await browser.waitForClickable(locator, N.globalTimeout()); action = "selectOption"; await browser.selectOption(locator, option); } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "selectOption"; await browser.selectOption(locator, option); } }); // allure.createStep("z select option " + locator + option); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators, option]; throw new Error("selectOption : Error while selecting value on element located by : " + locator); } } } /** * Checks for element to be present, scrolls into view & Moves cursor to element matched by locator. * Extra shift can be set with offsetX and offsetY options. * * ```js * z.moveCursorTo('.tooltip'); * z.moveCursorTo('#submit', 5,5); * ``` * * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator. * @param {number} [offsetX=0] (optional, `0` by default) X-axis offset. * @param {number} [offsetY=0] (optional, `0` by default) Y-axis offset. * * */ static async moveCursorTo(locators: string, offsetX?: number, offsetY?: number) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators); try { logger.info("Inside try block of moveCursorTo"); await I.wait(0); await allure.createStep(`z move Cursor To "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); } if (isNullOrUndefined(offsetX) && isNullOrUndefined(offsetY)) { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "moveCursorTo"; await browser.moveCursorTo(locator); } else if (isNullOrUndefined(offsetX) && !(isNullOrUndefined(offsetY))) { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "moveCursorTo"; await browser.moveCursorTo(locator, 0, offsetY); } else if (!(isNullOrUndefined(offsetX)) && isNullOrUndefined(offsetY)) { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "moveCursorTo"; await browser.moveCursorTo(locator, offsetX, 0); } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "moveCursorTo"; await browser.moveCursorTo(locator, offsetX, offsetY); } }); //allure.createStep("z move Cursor To " + locator); } catch (error) { try { logger.info("Inside catch block of moveCursorTo"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z move Cursor To "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); } if (isNullOrUndefined(offsetX) && isNullOrUndefined(offsetY)) { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "moveCursorTo"; await browser.moveCursorTo(locator); } else if (isNullOrUndefined(offsetX) && !(isNullOrUndefined(offsetY))) { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "moveCursorTo"; await browser.moveCursorTo(locator, 0, offsetY); } else if (!(isNullOrUndefined(offsetX)) && isNullOrUndefined(offsetY)) { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "moveCursorTo"; await browser.moveCursorTo(locator, offsetX, 0); } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "moveCursorTo"; await browser.moveCursorTo(locator, offsetX, offsetY); } }); // allure.createStep("z move Cursor To " + locator); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators, offsetX, offsetY]; throw new Error("moveCursorTo : Error while moving cursor to element located by : " + locator); } } } /** * Checks for element to be present, scrolls into view, waits for element to be visible and retrieves a value from a form element located by CSS or XPath, returns it to test. * Resumes test execution, so **should be used inside async function with `await`** operator. * * ```js * let email = await z.grabValueFrom('input[name=email]'); * ``` * @param {CodeceptJS.LocatorOrString} locator field located by label|name|CSS|XPath|strict locator. * @returns {Promise} attribute value * */ static async grabValueFrom(locators: string): Promise { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators); let value = ""; try { logger.info("Inside try block of grabValueFrom"); await I.wait(0); await allure.createStep(`z grab Value From "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator); action = "grabValueFrom"; value = await browser.grabValueFrom(locator); } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "grabValueFrom"; value = await browser.grabValueFrom(locator); } }); //allure.createStep("z grab Value From " + locator); } catch (error) { try { logger.info("Inside catch block of grabValueFrom"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z grab Value From "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator); action = "grabValueFrom"; value = await browser.grabValueFrom(locator); } else { action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "grabValueFrom"; value = await browser.grabValueFrom(locator); } }); // allure.createStep("z grab Value From " + locator); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators]; throw new Error("grabValueFrom : Error while grabbing value from element located by : " + locator); } } return value; } /** * Dismisses the active JavaScript popup, as created by window.alert|window.confirm|window.prompt. * ```js * await z.cancelPopup(); * ``` */ static async cancelPopup() { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; try { await I.wait(0); await allure.createStep("z cancel Pop up", async () => { action = "cancelPopup" await browser.cancelPopup(); }); } catch (error) { let timestamp = new Date().getTime(); await this.generateLog(timestamp, error); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "cancelPopup"; N.stepArgs = []; throw new Error("cancelPopup : Error while cancelling popup."); } } /** * Accepts the active JavaScript native popup window, as created by window.alert|window.confirm|window.prompt. * Don't confuse popups with modal windows, as created by [various * libraries](http://jster.net/category/windows-modals-popups). * ```js * await z.acceptPopup(); * ``` */ static async acceptPopup() { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; try { await I.wait(0); await allure.createStep("z accept Pop up", async () => { action = "acceptPopup" await browser.acceptPopup(); }); } catch (error) { let timestamp = new Date().getTime(); await this.generateLog(timestamp, error); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "acceptPopup"; N.stepArgs = []; throw new Error("acceptPopup : Error while accepting popup."); } } /** * Checks that the active JavaScript popup, as created by `window.alert|window.confirm|window.prompt`, contains the * given string. * * @param {string} text value to check. * * ```js * await z.seeInPopup("value"); * ``` * */ static async seeInPopup(text: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { await I.wait(0); await allure.createStep("z see in Pop up", async () => { await browser.seeInPopup(text); }); } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "seeInPopup"; N.stepArgs = [text]; await this.generateLog(timestamp, error); throw new Error("seeInPopup : Error while checking text in popup."); } } /** * Gets a cookie object by name. * If none provided gets all cookies. * Resumes test execution, so **should be used inside async function with `await`** operator. * * ```js * let cookie = await z.grabCookie('auth'); * assert(cookie.value, '123456'); * ``` * * @param {?string} [name=null] cookie name. * @returns {Promise} attribute value * */ static async grabCookie(name: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let cookie = ''; try { await I.wait(0); await allure.createStep("z grab cookie ", async () => { cookie = await browser.grabCookie(name); }); } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "grabCookie"; N.stepArgs = [name]; await this.generateLog(timestamp, error); throw new Error("grabCookie : Error fetching cookie."); } return cookie; } /** * Get current URL from browser * Resumes test execution, so **should be used inside async function with `await`** operator. * * ```js * let url = await z.grabCurrentUrl(); * ``` * */ static async grabCurrentUrl(): Promise { let url = ""; const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { await I.wait(0); await allure.createStep(`z grab Current Url "${url}"`, async () => { url = await browser.grabCurrentUrl(); }); } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "grabCurrentUrl"; await this.generateLog(timestamp, error); throw new Error("grabCurrentUrl : Error fetching current url."); } return url; } /** * Scrolls element into viewport, waits for that element to become visible & enabled, then Force clicks an element * ```js * z.forceClick('#hiddenButton'); * z.forceClick('Click me', '#hidden'); * ``` * @param {string} locator CSS|XPath|strict locator. * @param {string} context (optional, null by default) element to search in CSS|XPath|Strict locator. */ static async forceClick(locators: string, context?: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of forceClick"); await I.wait(0); await allure.createStep(`z force Click "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "waitForEnabled"; await browser.waitForEnabled(locator, N.globalTimeout()); if (isNullOrUndefined(context)) { action = "forceClick"; await browser.forceClick(locator); } else { action = "forceClick"; await browser.forceClick(locator, context); } } else { if (isNullOrUndefined(context)) { action = "forceClick"; await browser.forceClick(locator); } else { action = "forceClick"; await browser.forceClick(locator, context); } } }); // allure.createStep("z forceClick " + locator); } catch (error) { try { logger.info("Inside catch block of forceClick"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z force Click "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "waitForEnabled"; await browser.waitForEnabled(locator, N.globalTimeout()); if (isNullOrUndefined(context)) { action = "forceClick"; await browser.forceClick(locator); } else { action = "forceClick"; await browser.forceClick(locator, context); } } else { if (isNullOrUndefined(context)) { action = "forceClick"; await browser.forceClick(locator); } else { action = "forceClick"; await browser.forceClick(locator, context); } } }); // allure.createStep("z forceClick " + locator); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators]; throw new Error("forceClick : Error while clicking element located by : " + locator); } } } /** * Asserts that an element is visible a given number of times * ```js * await z..seeNumberOfVisibleElements('.buttons', 3); * ``` * @param {string} locator CSS|XPath|strict locator. * @param {number} num number of elements.. * */ static async seeNumberOfVisibleElements(locators: string, num: number) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of seeNumberOfVisibleElements"); await I.wait(0); await allure.createStep(`z see number of visible elements "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "seeNumberOfVisibleElements"; await browser.seeNumberOfVisibleElements(locator, num); } else { action = "seeNumberOfVisibleElements"; await browser.seeNumberOfVisibleElements(locator, num); } }); // allure.createStep("z see number of visible elements " + locator); } catch (error) { try { logger.info("Inside catch block of seeNumberOfVisibleElements"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z see number of visible elements "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "seeNumberOfVisibleElements"; await browser.seeNumberOfVisibleElements(locator, num); } else { action = "seeNumberOfVisibleElements"; await browser.seeNumberOfVisibleElements(locator, num); } }); // allure.createStep("z see number of visible elements " + locator); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator); N.stepName = action; N.stepArgs = [locators]; N.stepArgs = [num]; throw new Error("seeNumberOfVisibleElements : Error while asserting that an element " + locator + " is visible a given " + num + " number of times : "); } } } /** * Checks that title contains text. * ```js * z.seeInTitle('Home Page'); * ``` * @param {string} text value to check. */ static async seeInTitle(text: any) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { logger.info("Inside try block of seeInTitle"); await I.wait(0); await allure.createStep(`z see in title "${text}"`, async () => { await browser.seeInTitle(text); }); } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "seeInTitle"; N.stepArgs = [text]; await this.generateLog(timestamp, error); throw new Error("seeInTitle : Error while checking title contains text: " + text); } } /** * Performs a swipe Right inside an element. * Can be slow or fast swipe. * ```js * z.swipeRight('#container'); * * @param {string} locator an element on which to perform swipe * @param {string}[speed='slow'] a speed to perform: `slow` or `fast`. */ static async swipeRight(locators: string, speed?: string) { const browser = this.prototype.helpers['WebDriver']; let allure: any = codeceptjs.container.plugins('allure'); let locator = ''; locator = await this.getElements(locators) try { await I.wait(0); if (!isNullOrUndefined(speed)) { await allure.createStep(`z swipe Right "${locator}" with speed "${speed}"`, async () => { await browser.swipeRight(locator, speed); }); } else { await allure.createStep("z swipe Right " + locator, async () => { await browser.swipeRight(locator); }); } } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); // await this.createStep("z swipe Right ", locator); N.stepName = "swipeRight"; N.stepArgs = [locators]; throw new Error("swipeRight : Error performing swipe right inside an element " + locator); } } /** * Scrolls to element matched by locator. Extra shift can be set with offsetX and offsetY options. * ```js * z.scrollTo('footer'); * z.scrollTo('#submit', 5, 5); * ``` * @param {string} locator located by CSS|XPath|strict locator. * @param {number} offsetX (optional, 0 by default) X-axis offset * @param {number} offsetY (optional, 0 by default) Y-axis offset. * */ static async scrollTo(locators: string, offsetX?: number, offsetY?: number) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of scrollTo"); await I.wait(0); await allure.createStep(`z scrollTo "${locator}"`, async () => { if (!isNullOrUndefined(offsetX)) { await browser.scrollTo(locator, offsetX); //allure.createStep("z scrollTo " + locator + " with offsetX " + offsetX); } else if (!isNullOrUndefined(offsetY)) { await browser.scrollTo(locator, undefined, offsetY); // allure.createStep("z scrollTo " + locator + " with offsetY " + offsetY); } else if (!isNullOrUndefined(offsetX) && !isNullOrUndefined(offsetY)) { await browser.scrollTo(locator, offsetX, offsetY); // allure.createStep("z scrollTo " + locator + " with offsetX " + offsetX+ " with offsetY " + offsetY); } else { await browser.scrollTo(locator); // allure.createStep("z scrollTo " + locator); } }); } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); // allure.createStep("z scrollTo " + locator, this.cb()); N.stepName = "scrollTo"; N.stepArgs = [locators]; throw new Error("scrollTo : Error while scroll to element located by: " + locator); } } /** * Scroll page to the bottom. * ```js * z.scrollPageToBottom(); */ static async scrollPageToBottom() { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { logger.info("Inside try block of scrollPageToBottom"); await I.wait(0); await allure.createStep("z scroll Page To Bottom ", async () => { await browser.scrollPageToBottom(); }); } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); await this.generateLog(timestamp, error); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "scrollPageToBottom"; // allure.createStep("z scroll Page To Bottom", this.cb()); throw new Error("scrollPageToBottom : Error while scroll page to bottom "); } } /** * Scroll page to the top. * ```js * z.scrollPageToTop(); */ static async scrollPageToTop() { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { logger.info("Inside try block of scrollPageToTop"); await I.wait(0); await allure.createStep("z scroll Page To Top", async () => { await browser.scrollPageToTop(); }); } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); // allure.createStep("z scroll Page To Top", this.cb()); throw new Error("scrollPageToTop : Error while scroll page to top "); } } /** * Asserts that two values are not equal. If they are ,an assertion error is thrown. * ```js * z.assertNotEqual(expected,actual) * ``` * @param {any} expected * @param {any} actual */ static async assertNotEqual(expected: any, actual: any) { await I.assertNotEqual(expected, actual); } /** * Scrolls element into viewport, waits for that element to become visible. * Then Verifies that the specified checkbox is not checked. * * ```js * z.dontSeeCheckboxIsChecked('#agree'); * z.dontSeeCheckboxIsChecked('I agree to terms'); * z.dontSeeCheckboxIsChecked('agree'); * ``` * @param {string} field located by label|name|CSS|XPath|strict locator. */ static async dontSeeCheckboxIsChecked(locators: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators); try { logger.info("Inside try block of dontSeeCheckboxIsChecked"); await I.wait(0); await allure.createStep(`z dont See Checkbox Is Checked "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "dontSeeCheckboxIsChecked"; await browser.dontSeeCheckboxIsChecked(locator); } else { action = "dontSeeCheckboxIsChecked"; await browser.dontSeeCheckboxIsChecked(locator); } }); // allure.createStep("z dont See Checkbox Is Checked " + locator); } catch (error) { try { logger.info("Inside catch block of dontSeeCheckboxIsChecked"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z dont See Checkbox Is Checked "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "dontSeeCheckboxIsChecked"; await browser.dontSeeCheckboxIsChecked(locator); } else { action = "dontSeeCheckboxIsChecked"; await browser.dontSeeCheckboxIsChecked(locator); } }); // allure.createStep("z dont See Checkbox Is Checked " + locator); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators]; throw new Error("dontSeeCheckboxIsChecked : Error while verfiying checkbox is not checked: " + locator); } } } /** * Scrolls element into viewport, waits for that element to become visible. * Then Checks that the given input field or textarea equals to given value. * * ```js * z.seeInField('Username', 'davert'); * z.seeInField({css: 'form textarea'},'Type your comment here'); * z.seeInField('#searchform input','Search'); * ``` * @param {string} field located by label|name|CSS|XPath|strict locator. * @param {string} value value to check. */ static async seeInField(locators: string, value: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of seeInField"); await I.wait(0); await allure.createStep(`z see In Field "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "seeInField"; await browser.seeInField(locator, value); } else { await browser.seeInField(locator, value); } }); //allure.createStep("z see In Field " + locator); } catch (error) { try { logger.info("Inside try block of seeInField"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); await allure.createStep(`z see In Field "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "seeInField"; await browser.seeInField(locator, value); } else { await browser.seeInField(locator, value); } }); // allure.createStep("z see In Field " + locator); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators, value]; throw new Error("seeInField : Error while verfiying value in input field " + locator); } } } /** * Scrolls element into viewport, waits for that element to become visible. * Then Verifies that the specified checkbox is checked. * * ```js * z.seeCheckboxIsChecked('Agree'); * z.seeCheckboxIsChecked('#agree'); * z.seeCheckboxIsChecked({css: '#signup_form input[type=checkbox]'}); * ``` * @param {string} field located by label|name|CSS|XPath|strict locator. */ static async seeCheckboxIsChecked(locators: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of seeCheckboxIsChecked"); await I.wait(0); await allure.createStep(`z see checkbox is checked "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "waitForClickable"; await browser.waitForClickable(locator, N.globalTimeout()); action = "seeCheckboxIsChecked"; await browser.seeCheckboxIsChecked(locator); } else { action = "seeCheckboxIsChecked"; await browser.seeCheckboxIsChecked(locator); } }); // allure.createStep("z see checkbox is checked " + locator); } catch (error) { try { logger.info("Inside catch block of seeCheckboxIsChecked"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z see checkbox is checked "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "waitForClickable"; await browser.waitForClickable(locator, N.globalTimeout()); action = "seeCheckboxIsChecked"; await browser.seeCheckboxIsChecked(locator); } else { action = "seeCheckboxIsChecked"; await browser.seeCheckboxIsChecked(locator); } }); // allure.createStep("z see checkbox is checked " + locator); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators]; throw new Error("seeCheckboxIsChecked : Error while verfiying checkbox is checked: " + locator); } } } /** * Types out the given text into an active field. * To slow down typing use a second parameter, to set interval between key presses. * Note: Should be used when fillField is not an option. * ```js * z.type('Type this out.'); * * // typing values with a 100ms interval * z.type('4141555311111111', 100); * // When passing in an array * z.type(['T', 'E', 'X', 'T']) * * @param {string} key|keys key or array of keys to type. * @param {number} delay (optional) delay in ms between key presses */ static async type(key: string | string[], delay?: number) { const browser = this.prototype.helpers['WebDriver']; let allure: any = codeceptjs.container.plugins('allure'); try { logger.info("Inside try block of type"); await I.wait(0); await allure.createStep("z type " + key, async () => { if (isNullOrUndefined(delay)) { await browser.type(key) } else { await browser.type(key, delay) } }); // allure.createStep("z type " + key); } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); // allure.createStep("z type " + key, this.cb()); N.stepName = "type"; N.stepArgs = [key]; throw new Error("ERROR" + error + "\n" + key); } } /** * Resize the current window to provided width and height. * First parameter can be set to `maximize`. * ```js * z.resizeWindow(width, height) */ static async resizeWindow(width: any, height?: any) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { await I.wait(0); if (!isNullOrUndefined(height)) { await allure.createStep("z resize Window with width " + width + " height " + height, async () => { await browser.resizeWindow(width, height); }); // allure.createStep("z resize Window with width " + width+ " height "+height); } else { await allure.createStep("z resize Window with width " + width, async () => { await browser.resizeWindow(width, 0); }); } } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); // allure.createStep("z resize Window with width " + width, this.cb()); N.stepName = "resizeWindow"; N.stepArgs = [width]; throw new Error("resizeWindow : Error resizing the current window "); } } /** * Grab number of open tabs. * Resumes test execution, so **should be used inside async function with `await`** operator. * * ```js * let tabs = await z.grabNumberOfOpenTabs(); * ``` * */ static async grabNumberOfOpenTabs(): Promise { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let tabs = ''; try { await I.wait(0); await allure.createStep("z grabNumberOfOpenTabs ", async () => { tabs = await browser.grabNumberOfOpenTabs(); }); return tabs; } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); N.stepName = "grabNumberOfOpenTabs"; // allure.createStep("z grabNumberOfOpenTabs ", this.cb()); throw new Error("grabNumberOfOpenTabs : Error fetching number of open tabs."); } } /** * Checks that current url contains a provided fragment. * * @param {string} url value to check. * * ```js * await z.seeInCurrentUrl("url"); * ``` * */ static async seeInCurrentUrl(url: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { await I.wait(0); await allure.createStep(`z see In Current Url "${url}"`, async () => { await browser.seeInCurrentUrl(url); }); } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "seeInCurrentUrl"; await this.generateLog(timestamp, error); //allure.createStep("z see In Current Url " + url, this.cb()); throw new Error("seeInCurrentUrl : Error while seeing provided fragment " + url + " in current url"); } } /** * Retrieves a page title and returns it to test. * Resumes test execution, so **should be used inside async function with `await`** operator. * * ```js * let tabs = await z.grabTitle(); * ``` * */ static async grabTitle(): Promise { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let title = ''; try { await I.wait(0); await allure.createStep("z grab Title ", async () => { title = await browser.grabTitle(); }); return title; } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "grabTitle"; await this.generateLog(timestamp, error); // allure.createStep("z grab Title ", this.cb()); throw new Error("grabTitle : Error fetching title."); } } /** * Enters a directory In local filesystem. * Starts from a current directory * z.amInPath('output/downloads'); * @param {string} openPath */ static async amInPath(openPath: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { await I.wait(0); await allure.createStep(`z am In Path "${openPath}"`, async () => { await browser.amInPath(openPath); }) // allure.createStep("z am In Path ", this.cb()); } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); // allure.createStep("z am In Path ", this.cb()); throw new Error("amInPath: Error while entering a directory in filesysytem " + openPath); } } /** * Waits for file to be present in current directory. * * ```js * z.handleDownloads(); * z.click('Download large File'); * z.amInPath('output/downloads'); * z.waitForFile('largeFilesName.txt', 10); // wait 10 seconds for file * ``` * @param {string} name * @param {number} [sec] seconds to wait */ static async waitForFile(name: string, sec?: number) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { await I.wait(0); if (!isNullOrUndefined(sec)) { await allure.createStep("z wait For File " + name + ", for time " + sec + " seconds", async () => { await browser.waitForFile(name, sec); }); } else { await allure.createStep("z wait For File " + name, async () => { await browser.waitForFile(name); }); } } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); N.stepName = "waitForFile"; // allure.createStep("z wait For File " + name, this.cb()); throw new Error("waitForFile: Error while waiting for file to be present in current directory. " + name); } } /** * Checks that file with a name including given text exists in the current directory. * *```js * z.handleDownloads(); * z.click('Download as PDF'); * z.amInPath('output/downloads'); * z.seeFileNameMatching('.pdf'); * ``` */ static async seeFileNameMatching(text: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; try { logger.info("Inside try block of seeFileNameMatching"); await I.wait(0); action = "wait" await browser.wait(2); await allure.createStep("z see File Name Matching " + text, async () => { action = "seeFileNameMatching" await browser.seeFileNameMatching(text); }); } catch (error) { try { let timestamp = new Date().getTime(); await this.generateLog(timestamp, error); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } logger.info("Inside catch block of seeFileNameMatching"); action = "wait" await browser.wait(2); await allure.createStep("z see File Name Matching " + text, async () => { action = "seeFileNameMatching" await browser.seeFileNameMatching(text); }); // allure.createStep("z see File Name Matching " + text); } catch (error) { // allure.createStep("z see File Name Matching " + text, this.cb); N.stepName = action; N.stepArgs = [text]; throw new Error("seeFileNameMatching: Error while checking that file with a name including given text exists in the current directory. " + text); } } } /** * Checks that file found by `seeFile` doesn't include text. * @param {string} text * @param {string} [encoding='utf8'] */ static async dontSeeInThisFile(text: string, encoding?: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { logger.info("Inside try block of dontSeeInThisFile"); await I.wait(0); if (isNullOrUndefined(encoding)) { await allure.createStep("z dont see in this file " + text, async () => { await browser.dontSeeInThisFile(text); }); } else { await allure.createStep("z dont see in this file " + text + ", " + encoding, async () => { await browser.dontSeeInThisFile(text, encoding); }); } } catch (error) { try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } if (isNullOrUndefined(encoding)) { await allure.createStep("z dont see in this file " + text, async () => { await browser.dontSeeInThisFile(text); }); } else { await allure.createStep("z dont see in this file " + text + ", " + encoding, async () => { await browser.dontSeeInThisFile(text, encoding); }); } await this.generateLog(timestamp, error); } catch (error) { // allure.createStep("z dont see in this file " + text + " " + this.cb); N.stepName = "dontSeeInThisFile"; N.stepArgs = [text]; throw new Error("dontSeeInThisFile: Error while checking that file found doesn't include text. " + text); } } } /** * Checks that all elements with given locator have given attributes. * * ```js * z.seeAttributesOnElements('//form', { method: "post"}); * ``` * * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator. * @param {object} attributes attributes and their values to check. * */ static async seeAttributesOnElements(locators: string, attributes: any) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let locator = ''; let action = ""; locator = await this.getElements(locators) try { logger.info("Inside try block of seeAttributesOnElements"); await I.wait(0); await allure.createStep(`z see attributes on elements "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "seeAttributesOnElements"; await browser.seeAttributesOnElements(locator, attributes); } else { action = "seeAttributesOnElements"; await browser.seeAttributesOnElements(locator, attributes); } }); //allure.createStep("z see attributes on elements " + locator); } catch (error) { try { logger.info("Inside catch block of seeAttributesOnElements"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z see attributes on elements "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "seeAttributesOnElements"; await browser.seeAttributesOnElements(locator, attributes); } else { action = "seeAttributesOnElements"; await browser.seeAttributesOnElements(locator, attributes); } }); // allure.createStep("z see attributes on elements " + locator); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators, attributes]; throw new Error("seeAttributesOnElements: Error while checking that all elements with given locator have given attributes. " + locator); } } } /** * Checks that a given Element is present in the DOM * Element is located by CSS or XPath. * * ```js * z.seeElementInDOM('#modal'); * ``` * @param {string} locator element located by CSS|XPath|strict locator. * */ static async seeElementInDOM(locators: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of seeElementInDOM"); await I.wait(0); await allure.createStep("z see Element In DOM " + locator, async () => { await browser.seeElementInDOM(locator); }); } catch (error) { try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep("z see Element In DOM " + locator, async () => { await browser.seeElementInDOM(locator); }); await this.generateLog(timestamp, error); } catch (error) { // allure.createStep("z see Element In DOM " + locator, this.cb()); N.stepName = "seeElementInDOM"; N.stepArgs = [locators]; throw new Error("seeElementInDOM: Error while checking that a given Element is present in the DOM. " + locator); } } } /** * Appends text into the field. * A field can be located by text, accessibility id, id. * * ```js * z.appendField('name', 'davert'); * ``` * * @param {string} field * @param {string} value */ static async appendField(locators: string, value: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of appendField"); await I.wait(0); await allure.createStep(`zappend Field "${locator}", "${value}"`, async () => { action = "click"; await this.click(locator); action = "appendField"; await browser.appendField(locator, value); }); // await this.createStep(action, locator); } catch (error) { try { logger.info("Inside catch block of appendField"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`zappend Field "${locator}", "${value}"`, async () => { action = "click"; await this.click(locator); action = "appendField"; await browser.appendField(locator, value); }); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators]; throw new Error("appendField: Error while appending the text into the field.. " + locator); } } } /** * Waits for an element to become not attached to the DOM on a page (by default waits for 1sec). * Element can be located by CSS or XPath. * * ```js * z.waitForDetached('#popup'); * ``` * * @param {string} locator element located by CSS|XPath|strict locator. * @param {number} timeout (optional, `1` by default) time in seconds to wait */ static async waitForDetached(locators: string, timeout?: number) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of waitForDetached"); await I.wait(0); action = "waitForDetached" if (!isNullOrUndefined(timeout)) { await allure.createStep("z wait For Detached " + locator + ", for time " + timeout, async () => { await browser.waitForDetached(locator, timeout); }); } else { await allure.createStep("z wait For Detached " + locator, async () => { await browser.waitForDetached(locator); }); } } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); N.stepName = "waitForDetached"; N.stepArgs = [locators]; throw new Error("waitForDetached : Error while waiting for element to become not attached to the DOM located by : " + locator); } } /** * Sends POST request to API. * * ```js * I.sendPostRequest('/api/users.json', { "email": "user@user.com" }); * ``` * * @param {*} url * @param {*} payload * @param {object} headers */ static async sendPostRequest(url: any, payload?: any, headers?: any) { const browser = this.prototype.helpers['WebDriver']; const restHelper = this.prototype.helpers['REST']; let allure: any = codeceptjs.container.plugins('allure'); let response: any; try { await I.wait(0); await allure.createStep(`z send post request to "${url}","${payload}","${headers}"`, async () => { response = await restHelper.sendPostRequest(url, payload, headers); }); } catch (error) { try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z send post request to "${url}","${payload}","${headers}"`, async () => { response = await restHelper.sendPostRequest(url, payload, headers); }); await this.generateLog(timestamp, error); } catch (error) { // allure.createStep("z send post request to " + url + ", payload " + payload + ", header "+headers, this.cb()); N.stepName = "sendPostRequest"; N.stepArgs = [url, payload, headers]; throw new Error("sendPostRequest: Error while sending POST request to API."); } } return response; } /** * Send GET request to REST API * * ```js * I.sendGetRequest('/api/users.json'); * ``` * * @param {*} url * @param {object} headers */ static async sendGetRequest(url: any, headers?: any) { const browser = this.prototype.helpers['WebDriver']; const restHelper = this.prototype.helpers['REST']; let allure: any = codeceptjs.container.plugins('allure'); let response: any; try { await I.wait(0); await allure.createStep(`z send get request to "${url}","${headers}"`, async () => { response = await restHelper.sendGetRequest(url, headers); }); } catch (error) { try { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z send get request to "${url}","${headers}"`, async () => { response = await restHelper.sendGetRequest(url, headers); }); await this.generateLog(timestamp, error); } catch (error) { // allure.createStep("z send post request to " + url + ", header "+headers, this.cb()); N.stepName = "sendGetRequest"; N.stepArgs = [url, headers]; throw new Error("sendGetRequest: Error while sending GET request to REST API"); } } return response; } /** * Opposite to `seeElementInDOM`. Checks that element is not on page. * * ```js * I.dontSeeElementInDOM('.nav'); // checks that element is not on page visible or not * ``` * * @param {string} locator located by CSS|XPath|Strict locator. */ static async dontSeeElementInDOM(locators: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let locator = ""; locator = await this.getElements(locators) try { logger.info("Inside try block of dontSeeElementInDOM"); await I.wait(0); await allure.createStep("z dont see element in DOM " + locator, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { await browser.dontSeeElementInDOM(locator); } else { await browser.dontSeeElementInDOM(locator); } }); // allure.createStep("z dont see element in DOM "+locator); } catch (error) { try { logger.info("Inside catch block of dontSeeElementInDOM"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep("z dont see element in DOM " + locator, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { await browser.dontSeeElementInDOM(locator); } else { await browser.dontSeeElementInDOM(locator); } }); // allure.createStep("z dont see element in DOM "+locator); await this.generateLog(timestamp, error); } catch (error) { // allure.createStep("z dont see element in DOM "+locator , this.cb()); N.stepName = "dontSeeElementInDOM"; N.stepArgs = [locators]; throw new Error("dontSeeElementInDOM: Error while checking that element is not on page"); } } } /** * Checks that text is equal to provided one. * * ```js * I.seeTextEquals('text', 'h1'); * ``` * * @param {string} text element value to check. * @param {string} optional [context] element located by CSS|XPath|strict locator. */ static async seeTextEquals(text: string, context?: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; try { logger.info("Inside try block of seeTextEquals"); await I.wait(0); await allure.createStep(`z see Text Equals "${text}"`, async () => { if (isNullOrUndefined(context)) { await browser.wait(2); action = "seeTextEquals" await browser.seeTextEquals(text); // allure.createStep("z see Text Equals " + text); } else { action = "waitForVisible" await browser.waitForVisible(context); action = "seeTextEquals" await browser.seeTextEquals(text, context); // allure.createStep("z see Text Equals " + text); } }); } catch (error) { try { logger.info("Inside catch block of seeTextEquals"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z see Text Equals "${text}"`, async () => { if (isNullOrUndefined(context)) { await browser.wait(2); action = "seeTextEquals" await browser.seeTextEquals(text); // allure.createStep("z see Text Equals " + text); } else { action = "waitForVisible" await browser.waitForVisible(context); action = "seeTextEquals" await browser.seeTextEquals(text, context); // allure.createStep("z see Text Equals " + text); } }); await this.generateLog(timestamp, error); } catch (error) { // allure.createStep("z see Text Equals " + text, this.cb()); N.stepName = action; N.stepArgs = [text]; throw new Error("seeTextEquals: Error while checking that text is equal to provided one."); } } } /** * Checks that title is equal to provided one. * * ```js * z.seeTitleEquals('Test title.'); * ``` * * @param {string} text value to check. */ static async seeTitleEquals(text: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { await I.wait(0); await allure.createStep(`z see Title Equals "${text}"`, async () => { await browser.seeTitleEquals(text); }); } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); N.stepName = "seeTitleEquals"; N.stepArgs = [text]; // allure.createStep("z see Title Equals "+text, this.cb()); throw new Error("seeTitleEquals: Error while checking that title is equal to provided one."); } } /** * Clears a cookie by name, * if none provided clears all cookies. * * ```js * z.clearCookie(); * z.clearCookie('test'); * ``` * * @param {string} (optional, `null` by default) cookie name * */ static async clearCookie(cookie?: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { await I.wait(0); if (isNullOrUndefined(cookie)) { await allure.createStep("z clear Cookie ", async () => { await browser.clearCookie(); }); } else { await allure.createStep("z clear Cookie " + cookie, async () => { await browser.clearCookie(cookie); }); } } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); N.stepName = "clearCookie"; throw new Error("clearCookie: Error while clearing a cookie by name"); } } /** * Retrieves the innerHTML from an element located by CSS or XPath and returns it to test. * Resumes test execution, so **should be used inside async function with `await`** operator. * If more than one element is found - an array of HTMLs returned. * * ```js * let postHTML = await z.grabHTMLFrom('#post'); * ``` * * @param {CodeceptJS.LocatorOrString} element located by CSS|XPath|strict locator. * @returns {Promise} HTML code for an element */ static async grabHTMLFrom(locators: string): Promise { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators); let htmlForm = ""; try { logger.info("Inside try block of grabHTMLFrom"); await I.wait(0); await allure.createStep(`z grab HTML From "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "grabHTMLFrom"; htmlForm = await browser.grabHTMLFrom(locator); } else { htmlForm = await browser.grabHTMLFrom(locator); } }); } catch (error) { logger.info("Inside catch block of grabHTMLFrom"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); try { logger.info("Inside catch block of grabHTMLFrom"); await allure.createStep(`z grab HTML From "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "grabHTMLFrom"; htmlForm = await browser.grabHTMLFrom(locator); } else { htmlForm = await browser.grabHTMLFrom(locator); } }); // allure.createStep("z grab HTML From " + locator); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators]; throw new Error("grabHTMLFrom: Error while retrieving the innerHTML from an element " + locator); } } return htmlForm; } /** * Retrieves all the innerHTML from elements located by CSS or XPath and returns it to test. * Resumes test execution, so should be used inside async function with await operator. * * ```js * let postHTML = await z.grabHTMLFromAll('#post'); * ``` * * @param {CodeceptJS.LocatorOrString} element located by CSS|XPath|strict locator. * @returns {Promise} HTML code for an element */ static async grabHTMLFromAll(locators: string): Promise { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) let htmlForm: string; try { logger.info("Inside try block of grabHTMLFromAll"); await I.wait(0); await allure.createStep(`z grab HTML From All "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "grabHTMLFrom"; htmlForm = await browser.grabHTMLFromAll(locator); } else { htmlForm = await browser.grabHTMLFromAll(locator); } }); } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); try { if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep(`z grab HTML From All "${locator}"`, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "waitForElement"; await browser.waitForElement(locator, N.globalTimeout()); action = "scrollIntoView"; // await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) await this.scrollIntoViewWrapper(browser, locator, { behavior: "auto", block: "center", inline: "center" }); action = "waitForVisible"; await browser.waitForVisible(locator, N.globalTimeout()); action = "grabHTMLFrom"; htmlForm = await browser.grabHTMLFromAll(locator); } else { htmlForm = await browser.grabHTMLFromAll(locator); } }); // allure.createStep("z grab HTML From All " + locator); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator, N.globalTimeout()); N.stepName = action; N.stepArgs = [locators,]; throw new Error("grabHTMLFrom: Error while retrieving all the innerHTML from elements"); } } return htmlForm; } /** * Checks that current url does not contain a provided fragment. * * @param {string} url value to check. * Appium: support only web testing */ static async dontSeeInCurrentUrl(url: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { await I.wait(0); await allure.createStep(`z dont See In Current Url "${url}"`, async () => { await browser.dontSeeInCurrentUrl(url); }); } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); N.stepName = "dontSeeInCurrentUrl"; N.stepArgs = [url]; // allure.createStep("z dont See In Current Url "+url, this.cb()); throw new Error("dontSeeInCurrentUrl: Error while checking current url does not contain a provided fragment"); } } /** * Checks that current url is equal to provided one. * If a relative url provided, a configured url will be prepended to it. * So both examples will work: * * ```js * z.seeCurrentUrlEquals('/register'); * z.seeCurrentUrlEquals('http://my.site.com/register'); * ``` * * @param {string} url value to check. */ static async seeCurrentUrlEquals(url: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { await I.wait(0); await allure.createStep("z see In Current Url " + url, async () => { await browser.seeCurrentUrlEquals(url); }); } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); N.stepName = "seeCurrentUrlEquals"; N.stepArgs = [url]; // allure.createStep("z See In Current Url "+url, this.cb()); throw new Error("seeCurrentUrlEquals: Error while checking that current url is equal to provided one."); } } /** * Asserts that an element appears a given number of times in the DOM. * Element is located by label or name or CSS or XPath. * * * ```js * z.seeNumberOfElements('#submitBtn', 1); * ``` * * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator. * @param {number} num number of elements. * * {{ react }} */ static async seeNumberOfElements(locators: string, num: number) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); let action = ""; let locator = ''; locator = await this.getElements(locators) try { logger.info("Inside try block of seeNumberOfElements"); await I.wait(0); await allure.createStep("z see number of elements " + locator, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "seeNumberOfElements"; await browser.seeNumberOfElements(locator, num); } else { action = "seeNumberOfElements"; await browser.seeNumberOfElements(locator, num); } }); // allure.createStep("z see number of elements " + locator); } catch (error) { try { logger.info("Inside catch block of seeNumberOfElements"); let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await allure.createStep("z see number of elements " + locator, async () => { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { action = "seeNumberOfElements"; await browser.seeNumberOfElements(locator, num); } else { action = "seeNumberOfElements"; await browser.seeNumberOfElements(locator, num); } }); // allure.createStep("z see number of elements " + locator); await this.generateLog(timestamp, error); } catch (error) { // await this.createStep(action, locator); N.stepName = action; N.stepArgs = [locators]; N.stepArgs = [num]; throw new Error("seeNumberOfElements : Error while asserting that an element " + locator + " is appears " + num + " number of times : "); } } } /** * Checks that cookie with given name does not exist. * * ```js * z.dontSeeCookie('auth'); // no auth cookie * ``` * * @param {string} name cookie name. * */ static async dontSeeCookie(name: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { await I.wait(0); await allure.createStep("z dont See Cookie " + name, async () => { await browser.dontSeeCookie(name); }); } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); N.stepName = "dontSeeCookie"; N.stepArgs = [name]; //allure.createStep("z dont See Cookie "+name, this.cb()); throw new Error("dontSeeCookie: Error while checking that cookie with given name does not exist."); } } /** * Checks that current url is not equal to provided one. * If a relative url provided, a configured url will be prepended to it. * * ```js * z.dontSeeCurrentUrlEquals('/login'); // relative url are ok * z.dontSeeCurrentUrlEquals('http://mysite.com/login'); // absolute urls are also ok * ``` * * @param {string} url value to check. * */ static async dontSeeCurrentUrlEquals(url: string) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { await I.wait(0); await allure.createStep("z dont see In Current Url " + url, async () => { await browser.dontSeeCurrentUrlEquals(url); }); } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } await this.generateLog(timestamp, error); N.stepName = "dontSeeCurrentUrlEquals"; N.stepArgs = [url]; // allure.createStep("z dont see In Current Url "+url, this.cb()); throw new Error("dontSeeCurrentUrlEquals: Error while checking that current url is not equal to provided one."); } } /** * Checks that title does not contain text. * * ```js * z.dontSeeInTitle('Error'); * ``` * * @param {string} text value to check. * */ static async dontSeeInTitle(text: any) { const browser = await this.getHelper(); let allure: any = codeceptjs.container.plugins('allure'); try { logger.info("Inside try block of dontSeeInTitle"); await I.wait(0); await allure.createStep("z dont see in title " + text, async () => { await browser.dontSeeInTitle(text); }); } catch (error) { let timestamp = new Date().getTime(); await browser.saveScreenshot(timestamp.toString() + ".png"); if (await browser.grabNumberOfVisibleElements("//dew-notification-tray//dew-btn[@class='dew-btn']//button") > 0) { logger.info("click on notification") await browser.click("//dew-notification-tray//dew-btn[@class='dew-btn']//button") await browser.click("//dew-notification-tray//button[@class='au--wc--btn btn primary btn-modal']//span") } N.stepName = "dontSeeInTitle"; N.stepArgs = [text]; // allure.createStep("z dont see in title " + text, this.cb()); await this.generateLog(timestamp, error); throw new Error("dontSeeInTitle : Error while checking title does not contain text: " + text); } } /** * Checks that the current page does not contains the given string in its raw source code. * * ```js * z.dontSeeInSource(' ${key}`); let sessionArray = (value as any)["test"]["sessions"]; for (const element of sessionArray) { sessionId = element["id"]; if(sessions.sessionId.includes(sessionId)) { console.log(`id --> ${sessionId}`); break; } } break; } } console.log(`Session id retrieved\n${sessionId}`); let secresponse = await restHelper.sendGetRequest(`http://${ipAdress}:${port}/download/${sessionId}`); console.log(`Response from session api\n${JSON.stringify( secresponse.data)}`); let defaultCxmlDocument = new DOMParser().parseFromString(secresponse.data, "application/xml"); ///////////////To get latest fiel downloaded/////////// let fileIndex = (defaultCxmlDocument.documentElement.getElementsByTagName("a").length-1); let fileName = defaultCxmlDocument.documentElement.getElementsByTagName("a")[fileIndex].getAttribute("href"); /////////// To get first file downloaded(we can pass index instead of zero) // let fileName = defaultCxmlDocument.documentElement.getElementsByTagName("a")[0].getAttribute("href"); console.log(`File name\n${fileName}`); let newFileName = "./tempDownload/"+fileName; if(expectedFileName) { newFileName = "./tempDownload/" + expectedFileName; } let file = fs.createWriteStream(newFileName); // const file = fs.createWriteStream("./tempDownload/"+fileName); await new Promise(function(resolve, reject){ http.get(`http://${ipAdress}:${port}/download/${sessionId}/${fileName}`, (response) => { response.pipe(file); setTimeout(() => { resolve(true); }, 10000); }); }); return "./tempDownload/"+fileName; } /** * Starts the browser explicitly. * * ```js * await z.startBrowser(); * ``` */ static async startBrowser() { try { console.log("========================>Start the Browser"); await this.prototype.helpers[helper]._startBrowser(); } catch (err) { console.log("========================>ERROR"+err); console.log("========================>Starting the Browser Failed..."); } } /** * Stops the browser explicitly. * * ```js * await z.stopBrowser(); * ``` */ static async stopBrowser() { try { console.log("========================>Stop the Browser"); await this.prototype.helpers[helper]._stopBrowser(); } catch (err) { console.log("========================>ERROR"+err); console.log("========================>Stopping the Browser Failed..."); } } //============================================= static async getElements(locator: string) { let finalLocators = locator; // if(runAutoheal === "true") { if(process.env.RUN_AUTOHEAL === "true") { let randomNumber = Math.random(); logger.info(randomNumber + "::::locator ::::::::: " + locator) if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { logger.info(randomNumber + "::::ohhh some one passed xpath") } else if (locator.includes("/") || locator.includes(".")) { logger.info(randomNumber + ":::: wowww Element key passed for : " + locator) let availableLocators: string[] = ['xPath', 'absolutePath', 'cssSelector', 'id', 'className']; let primaryLocatorType = await N.uiElements.get(locator)!.primaryLocator let locatorValue: string = await this.getLocator(locator, primaryLocatorType) logger.info(randomNumber + "::::trying with primary locator ::::::" + primaryLocatorType + "====>" + locatorValue) finalLocators = locatorValue; if (await this.getElementStatus(locatorValue)) { //primaryLocatorType === 'xPath' && if (N.uiElements.get(locator)!.isElementUpdated === false) { // make getall async await this.getAllLocators(locatorValue, locator, primaryLocatorType); //write compare logic N.uiElements.get(locator)!.isElementUpdated = true; let classnames = await N.uiElements.get(locator)!.className; console.log("classnames : " + classnames); if (classnames.includes("au-")) { let statussss = await this.checkUniqueNess(classnames) if (statussss) { console.log("primary locator changed to class name ") N.uiElements.get(locator)!.primaryLocator = "className"; } } else { let envVar = `Locator='${locator} || Value ='${classnames}' \n`; fs.appendFile("./output/UniqueClassNameStatusReport.txt", envVar, function (err) { if (err) throw err; console.log("Saved!"); }); //write logic for reporting } } finalLocators = locatorValue; } else { logger.info(randomNumber + "::::primary locator not worked ::::::::::::::::::" + primaryLocatorType + "====>" + locatorValue) let envVar = `Locator='${locator} || 'Type='${primaryLocatorType}' || Value ='${locatorValue}' \n`; fs1.appendFile("./output/PrimaryLocatorStatusReport.txt", envVar, function (err) { if (err) throw err; console.log("Saved!"); }); //write logic for reporting N.uiElements.get(locator)!.retryCount = N.uiElements.get(locator)!.retryCount + 1; for (let i = 0; i < availableLocators.length; i++) { if (availableLocators[i] !== primaryLocatorType) { let locator_Value: string = await this.getLocator(locator, availableLocators[i]) if (locator_Value == null || locator_Value == "null" || locator_Value == undefined) { logger.info(" Locator is NULL"); } else { logger.info(randomNumber + "::::trying with :::::::::::::::" + availableLocators[i] + "===>" + locator_Value) if (await this.getElementStatus(locator_Value)) { if (availableLocators[i] === 'xPath' || availableLocators[i] === 'absolutePath' && N.uiElements.get(locator)!.isElementUpdated === false) { await this.getAllLocators(locator_Value, locator, availableLocators[i]); //write compare logic N.uiElements.get(locator)!.isElementUpdated = true; let classnamess = await N.uiElements.get(locator)!.className; console.log("classnamess : " + classnamess); if (classnamess.includes("au-")) { let statusssss = await this.checkUniqueNess(classnamess) if (statusssss) { console.log("primary locator changed to class name ") N.uiElements.get(locator)!.primaryLocator = "className"; } } else { let envVar = `Locator='${locator} || Value ='${classnamess}' \n`; fs.appendFile("./output/UniqueClassNameStatusReport.txt", envVar, function (err) { if (err) throw err; console.log("Saved!"); }); } } if (N.uiElements.get(locator)!.retryCount > 2) { N.uiElements.get(locator)!.primaryLocator = availableLocators[i] logger.info(randomNumber + "::::Retry count excedded by 3 for current primary locator changing new primary locator ::::::::::::::" + availableLocators[i]) N.uiElements.get(locator)!.retryCount = 0; } finalLocators = locator_Value break; } } } } } logger.info(randomNumber + "::::returning locators : " + finalLocators); } else { finalLocators = "//*[contains(text(),'" + locator + "') or contains(@aria-label,'" + locator + "')]"; logger.info("Locator passed " + locator + " created xpath is " + finalLocators); } logger.info(randomNumber + "::::returning locatorsssss---- : " + finalLocators); } else { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { let randomNumber = Math.random(); logger.info(randomNumber + "::::ohhh some one passed xpath"); } else { if(N.uiElements.get(locator)) { finalLocators = await N.uiElements.get(locator).xpath; } } } return finalLocators; } static async getAllAttributes(locator: string, locatorType: string): Promise { if (locator === 'label') { locator = "//*[text()='" + locator + "']" return await z.executeScript(function (locator: string) { let nodeT: any = document.evaluate(locator, document, null, XPathResult.ANY_TYPE, null).iterateNext(); return nodeT.attributes }, locator); } else if (locatorType === 'cssSelector') { logger.info('else33') return await z.executeScript(function (locator: string) { return (document).querySelector(locator).attributes }, locator); } else if (locatorType == 'xPath' || locatorType == 'absolutePath') { logger.info("else 1") return await z.executeScript(function (locator: string) { let nodeT: any = document.evaluate(locator, document, null, XPathResult.ANY_TYPE, null).iterateNext() return nodeT.attributes }, locator); } else if (locatorType === 'id') { logger.info("else 2") return await z.executeScript(function (locator: string) { return (document).getElementById(locator).attributes }, locator); } else if (locatorType === 'className') { locator = locator.replace(/\./g, ' '); logger.info('else3:::' + locator) return await z.executeScript(function (locator: string) { return (document).getElementsByClassName(locator)[0].attributes; }, locator); } } // static async printAllAttributes(xpath: string) { // let nodemap = await this.getAllAttributes(xpath) // Array.prototype.slice.call(nodemap).forEach(function (item) { // logger.info(item.name + ': ' + item.value); // }); // } static async getText(locator: string, locatorType: string): Promise { if (locatorType === 'xPath' || locatorType === 'absolutePath') { return await z.executeScript(function (locator: string) { return (document).evaluate(locator, document, null, XPathResult.ANY_TYPE, null).iterateNext().textContent }, locator); } else if (locatorType === 'id') { return await z.executeScript(function (locator: string) { return (document).getElementById(locator).textContent }, locator); } else if (locatorType === 'className') { locator = locator.replace(/\./g, ' '); return await z.executeScript(function (locator: string) { return (document).getElementsByClassName(locator)[0].textContent }, locator); } else if (locatorType === 'cssSelector') { return await z.executeScript(function (locator: string) { return (document).querySelector(locator).textContent }, locator); } } //get absolute path static async getElementAbsolutePath(locator: string, locatorType: string) { if (locatorType === 'id') { let path: string[] = await z.executeScript(function (locator: string) { let el: any = (document).getElementById(locator).parentElement.firstChild; var stack: string[] = []; if (el !== null) while (el.parentNode != null) { var sibCount = 0; var sibIndex = 0; for (var i = 0; i < el.parentNode.childNodes.length; i++) { var sib = el.parentNode.childNodes[i]; if (sib.nodeName == el.nodeName) { if (sib === el) { sibIndex = sibCount; } sibCount++; } } if (sibCount > 1) { let indexes = sibIndex + 1 stack.unshift(el.nodeName.toLowerCase() + '[' + indexes + ']'); } else { stack.unshift(el.nodeName.toLowerCase()); } el = el.parentNode; } return stack; }, locator); let absolutepath: string = ""; path.forEach(function (value) { absolutepath = absolutepath + value + "/" }) return absolutepath.slice(0, absolutepath.length - 1) } else if (locatorType === 'xPath' || locatorType === 'absolutePath') { let path: string[] = await z.executeScript(function (locator: string) { let el = document.evaluate(locator, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue var stack: string[] = []; if (el !== null) while (el.parentNode != null) { var sibCount = 0; var sibIndex = 0; for (var i = 0; i < el.parentNode.childNodes.length; i++) { var sib = el.parentNode.childNodes[i]; if (sib.nodeName == el.nodeName) { if (sib === el) { sibIndex = sibCount; } sibCount++; } } if (sibCount > 0) { let indexes = sibIndex + 1 stack.unshift(el.nodeName.toLowerCase() + '[' + indexes + ']'); } else { stack.unshift(el.nodeName.toLowerCase()); } el = el.parentNode; } return stack; }, locator); let absolutepath: string = ""; path.forEach(function (value) { absolutepath = absolutepath + value + "/" }) return "/" + absolutepath.slice(0, absolutepath.length - 1); } else if (locatorType === 'className') { locator = locator.replace(/\./g, ' '); let path: string[] = await z.executeScript(function (locator: string) { let el: any = (document).getElementsByClassName(locator)[0].parentElement.firstChild; var stack: string[] = []; if (el !== null) while (el.parentNode != null) { var sibCount = 0; var sibIndex = 0; for (var i = 0; i < el.parentNode.childNodes.length; i++) { var sib = el.parentNode.childNodes[i]; if (sib.nodeName == el.nodeName) { if (sib === el) { sibIndex = sibCount; } sibCount++; } } if (sibCount > 1) { let indexes = sibIndex + 1 stack.unshift(el.nodeName.toLowerCase() + '[' + indexes + ']'); } else { stack.unshift(el.nodeName.toLowerCase()); } el = el.parentNode; } return stack; }, locator); let absolutepath: string = ""; path.forEach(function (value) { absolutepath = absolutepath + value + "/" }) return absolutepath.slice(0, absolutepath.length - 1) } else if (locatorType === 'cssSelector') { let path: string[] = await z.executeScript(function (locator: string) { let el: any = document.querySelector(locator).parentElement.firstChild; var stack: string[] = []; if (el !== null) while (el.parentNode != null) { var sibCount = 0; var sibIndex = 0; for (var i = 0; i < el.parentNode.childNodes.length; i++) { var sib = el.parentNode.childNodes[i]; if (sib.nodeName == el.nodeName) { if (sib === el) { sibIndex = sibCount; } sibCount++; } } if (sibCount > 1) { let indexes = sibIndex + 1 stack.unshift(el.nodeName.toLowerCase() + '[' + indexes + ']'); } else { stack.unshift(el.nodeName.toLowerCase()); } el = el.parentNode; } return stack; }, locator); let absolutepath: string = ""; path.forEach(function (value) { absolutepath = absolutepath + value + "/" }) return absolutepath.slice(0, absolutepath.length - 1) } else if (locatorType === 'label') { locator = "//*[text()='" + locator + "']" let path: string[] = await z.executeScript(function (locator: string) { let el = document.evaluate(locator, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue var stack: string[] = []; if (el !== null) while (el.parentNode != null) { var sibCount = 0; var sibIndex = 0; for (var i = 0; i < el.parentNode.childNodes.length; i++) { var sib = el.parentNode.childNodes[i]; if (sib.nodeName == el.nodeName) { if (sib === el) { sibIndex = sibCount; } sibCount++; } } if (sibCount > 1) { let indexes = sibIndex + 1 stack.unshift(el.nodeName.toLowerCase() + '[' + indexes + ']'); } else { stack.unshift(el.nodeName.toLowerCase()); } el = el.parentNode; } return stack; }, locator); let absolutepath: string = ""; path.forEach(function (value) { absolutepath = absolutepath + value + "/" }) return absolutepath.slice(0, absolutepath.length - 1) } } //get element css path by xpath static async getElementCssSelector(locator: string, locatorType: string) { if (locatorType === 'id') { let paths: string[] = await z.executeScript(function (locator: string) { let elSrc: any = (document).getElementById(locator).parentElement.firstChild; if (!(elSrc instanceof Element)) return; var sSel, aAttr = ['name', 'value', 'title', 'formcontrolname', 'aria-label', 'placeholder', 'data-*'], // Common attributes aSel: string[] = [], // Derive selector from element getSelector = function (el: any) { // 1. Check ID first if (el.id) { aSel.unshift('#' + el.id); return true; } aSel.unshift(sSel = el.nodeName.toLowerCase()); // 2. Try to select by classes if (el.className) { aSel[0] = sSel += '.' + el.className.trim().replace(/ +/g, '.'); if (uniqueQuery()) return true; } // 3. Try to select by classes + attributes for (var i = 0; i < aAttr.length; ++i) { if (aAttr[i] === 'data-*') { // Build array of data attributes var aDataAttr: any[] = [].filter.call(el.attributes, function (attr: any) { return attr.name.indexOf('data-') === 0; }); for (var j = 0; j < aDataAttr.length; ++j) { aSel[0] = sSel += '[' + aDataAttr[j].name + '="' + aDataAttr[j].value + '"]'; if (uniqueQuery()) return true; } } else if (el[aAttr[i]]) { aSel[0] = sSel += '[' + aAttr[i] + '="' + el[aAttr[i]] + '"]'; if (uniqueQuery()) return true; } } // 4. Try to select by nth-of-type() as a fallback for generic elements var elChild = el, sChild, n = 1; while (elChild = elChild.previousElementSibling) { if (elChild.nodeName === el.nodeName) ++n; } aSel[0] = sSel += ':nth-of-type(' + n + ')'; if (uniqueQuery()) return true; // 5. Try to select by nth-child() as a last resort elChild = el; n = 1; while (elChild = elChild.previousElementSibling) ++n; aSel[0] = sSel = sSel.replace(/:nth-of-type\(\d+\)/, n > 1 ? ':nth-child(' + n + ')' : ':first-child'); if (uniqueQuery()) return true; return false; }, // Test query to see if it returns one element uniqueQuery = function () { return (document).querySelectorAll(aSel.join('>') || null).length === 1; }; // Walk up the DOM tree to compile a unique selector while (elSrc.parentNode) { if (getSelector(elSrc)) return aSel.join(' > '); elSrc = elSrc.parentNode; } }, locator); return paths.toString(); // let absolutepath: string = ""; // path.forEach(function (value) { absolutepath = absolutepath + value + "/" }) // return absolutepath.slice(0, absolutepath.length - 1); } else if (locatorType === 'xPath' || locatorType === 'absolutePath') { let paths: string[] = await z.executeScript(function (locator: string) { let elSrc = document.evaluate(locator, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue if (!(elSrc instanceof Element)) return; var sSel, aAttr = ['name', 'value', 'title', 'formcontrolname', 'aria-label', 'placeholder', 'data-*'], // Common attributes aSel: string[] = [], // Derive selector from element getSelector = function (el: any) { // 1. Check ID first if (el.id) { aSel.unshift('#' + el.id); return true; } aSel.unshift(sSel = el.nodeName.toLowerCase()); // 2. Try to select by classes if (el.className) { aSel[0] = sSel += '.' + el.className.trim().replace(/ +/g, '.'); if (uniqueQuery()) return true; } // 3. Try to select by classes + attributes for (var i = 0; i < aAttr.length; ++i) { if (aAttr[i] === 'data-*') { // Build array of data attributes var aDataAttr: any[] = [].filter.call(el.attributes, function (attr: any) { return attr.name.indexOf('data-') === 0; }); for (var j = 0; j < aDataAttr.length; ++j) { aSel[0] = sSel += '[' + aDataAttr[j].name + '="' + aDataAttr[j].value + '"]'; if (uniqueQuery()) return true; } } else if (el[aAttr[i]]) { aSel[0] = sSel += '[' + aAttr[i] + '="' + el[aAttr[i]] + '"]'; if (uniqueQuery()) return true; } } // 4. Try to select by nth-of-type() as a fallback for generic elements var elChild = el, sChild, n = 1; while (elChild = elChild.previousElementSibling) { if (elChild.nodeName === el.nodeName) ++n; } aSel[0] = sSel += ':nth-of-type(' + n + ')'; if (uniqueQuery()) return true; // 5. Try to select by nth-child() as a last resort elChild = el; n = 1; while (elChild = elChild.previousElementSibling) ++n; aSel[0] = sSel = sSel.replace(/:nth-of-type\(\d+\)/, n > 1 ? ':nth-child(' + n + ')' : ':first-child'); if (uniqueQuery()) return true; return false; }, // Test query to see if it returns one element uniqueQuery = function () { return (document).querySelectorAll(aSel.join('>') || null).length === 1; }; // Walk up the DOM tree to compile a unique selector while (elSrc.parentNode) { if (getSelector(elSrc)) return aSel.join(' > '); elSrc = elSrc.parentNode; } }, locator); return paths.toString(); // let absolutepath: string = ""; // path.forEach(function (value) { absolutepath = absolutepath + value + "/" }) // return absolutepath.slice(0, absolutepath.length - 1); } else if (locatorType === 'className') { locator = locator.replace(/\./g, ' '); let paths: string[] = await z.executeScript(function (locator: string) { let elSrc: any = (document).getElementsByClassName(locator)[0].parentElement.firstChild; if (!(elSrc instanceof Element)) return; var sSel, aAttr = ['name', 'value', 'title', 'formcontrolname', 'aria-label', 'placeholder', 'data-*'], // Common attributes aSel: string[] = [], // Derive selector from element getSelector = function (el: any) { // 1. Check ID first if (el.id) { aSel.unshift('#' + el.id); return true; } aSel.unshift(sSel = el.nodeName.toLowerCase()); // 2. Try to select by classes if (el.className) { aSel[0] = sSel += '.' + el.className.trim().replace(/ +/g, '.'); if (uniqueQuery()) return true; } // 3. Try to select by classes + attributes for (var i = 0; i < aAttr.length; ++i) { if (aAttr[i] === 'data-*') { // Build array of data attributes var aDataAttr: any[] = [].filter.call(el.attributes, function (attr: any) { return attr.name.indexOf('data-') === 0; }); for (var j = 0; j < aDataAttr.length; ++j) { aSel[0] = sSel += '[' + aDataAttr[j].name + '="' + aDataAttr[j].value + '"]'; if (uniqueQuery()) return true; } } else if (el[aAttr[i]]) { aSel[0] = sSel += '[' + aAttr[i] + '="' + el[aAttr[i]] + '"]'; if (uniqueQuery()) return true; } } // 4. Try to select by nth-of-type() as a fallback for generic elements var elChild = el, sChild, n = 1; while (elChild = elChild.previousElementSibling) { if (elChild.nodeName === el.nodeName) ++n; } aSel[0] = sSel += ':nth-of-type(' + n + ')'; if (uniqueQuery()) return true; // 5. Try to select by nth-child() as a last resort elChild = el; n = 1; while (elChild = elChild.previousElementSibling) ++n; aSel[0] = sSel = sSel.replace(/:nth-of-type\(\d+\)/, n > 1 ? ':nth-child(' + n + ')' : ':first-child'); if (uniqueQuery()) return true; return false; }, // Test query to see if it returns one element uniqueQuery = function () { return (document).querySelectorAll(aSel.join('>') || null).length === 1; }; // Walk up the DOM tree to compile a unique selector while (elSrc.parentNode) { if (getSelector(elSrc)) return aSel.join(' > '); elSrc = elSrc.parentNode; } }, locator); return paths.toString(); // let absolutepath: string = ""; // path.forEach(function (value) { absolutepath = absolutepath + value + "/" }) // return absolutepath.slice(0, absolutepath.length - 1); } else if (locatorType === 'label') { locator = "//*[text()='" + locator + "']" let paths: string[] = await z.executeScript(function (locator: string) { let elSrc = document.evaluate(locator, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue if (!(elSrc instanceof Element)) return; var sSel, aAttr = ['name', 'value', 'title', 'formcontrolname', 'aria-label', 'placeholder', 'data-*'], // Common attributes aSel: string[] = [], // Derive selector from element getSelector = function (el: any) { // 1. Check ID first if (el.id) { aSel.unshift('#' + el.id); return true; } aSel.unshift(sSel = el.nodeName.toLowerCase()); // 2. Try to select by classes if (el.className) { aSel[0] = sSel += '.' + el.className.trim().replace(/ +/g, '.'); if (uniqueQuery()) return true; } // 3. Try to select by classes + attributes for (var i = 0; i < aAttr.length; ++i) { if (aAttr[i] === 'data-*') { // Build array of data attributes var aDataAttr: any[] = [].filter.call(el.attributes, function (attr: any) { return attr.name.indexOf('data-') === 0; }); for (var j = 0; j < aDataAttr.length; ++j) { aSel[0] = sSel += '[' + aDataAttr[j].name + '="' + aDataAttr[j].value + '"]'; if (uniqueQuery()) return true; } } else if (el[aAttr[i]]) { aSel[0] = sSel += '[' + aAttr[i] + '="' + el[aAttr[i]] + '"]'; if (uniqueQuery()) return true; } } // 4. Try to select by nth-of-type() as a fallback for generic elements var elChild = el, sChild, n = 1; while (elChild = elChild.previousElementSibling) { if (elChild.nodeName === el.nodeName) ++n; } aSel[0] = sSel += ':nth-of-type(' + n + ')'; if (uniqueQuery()) return true; // 5. Try to select by nth-child() as a last resort elChild = el; n = 1; while (elChild = elChild.previousElementSibling) ++n; aSel[0] = sSel = sSel.replace(/:nth-of-type\(\d+\)/, n > 1 ? ':nth-child(' + n + ')' : ':first-child'); if (uniqueQuery()) return true; return false; }, // Test query to see if it returns one element uniqueQuery = function () { return (document).querySelectorAll(aSel.join('>') || null).length === 1; }; // Walk up the DOM tree to compile a unique selector while (elSrc.parentNode) { if (getSelector(elSrc)) return aSel.join(' > '); elSrc = elSrc.parentNode; } }, locator); return paths.toString(); // let absolutepath: string = ""; // path.forEach(function (value) { absolutepath = absolutepath + value + "/" }) // return absolutepath.slice(0, absolutepath.length - 1); } } static async getAllLocators(locator: string, elementKey: string, locatorType: string) { try { logger.info(" ") logger.info(" ") logger.info(" ") logger.info(" ") let visibleFlag = true; if (visibleFlag) { logger.info("==================locator============================" + new Date().toLocaleString()) logger.info("locator : " + locator) //========================================================================== logger.info("----------------Attributes : ") let nodemap = await this.getAllAttributes(locator, locatorType) let classname = 'Null'; let ids = 'Null'; Array.prototype.slice.call(nodemap).forEach(function (item) { logger.info(item.name + ': ' + item.value); if (item.name === 'class') { classname = item.value } else if (item.name === 'id') { ids = item.value } }); if (classname !== "") { if (classname.includes("au-")) { let classnames = classname.split(" ") classname = classnames.find( function (classnames) { return classnames.includes("au-"); } ); } classname = await classname.replace(/\ /g, '.'); classname = "." + classname; console.log("new class name ::::::::::::::"+classname) N.uiElements.get(elementKey)!.className = classname } if (ids !== "") { N.uiElements.get(elementKey)!.id = ids } //========================================================================== logger.info("----------------Text : ") let text = await this.getText(locator, locatorType) logger.info("text : " + text) if (text !== "") { N.uiElements.get(elementKey)!.label = text.replace(/"/g, "'"); } //========================================================================== let absPath = ''; logger.info("----------------Absolute xpath :") absPath = await this.getElementAbsolutePath(locator, locatorType) as string; logger.info(" Absolute Xpath : " + absPath) if (absPath !== "" || absPath !== undefined) { N.uiElements.get(elementKey)!.absolutePath = absPath.replace(/"/g, "'"); } //========================================================================== logger.info("----------------css locator : ") let cssSelector = await this.getElementCssSelector(locator, locatorType) as string; logger.info(" css locator : " + cssSelector) if (cssSelector !== "") { N.uiElements.get(elementKey)!.cssSelector = cssSelector.replace(/"/g, "'"); } } } catch (error) { logger.info("error in getall.........................." + error) } logger.info(" ") logger.info(" ") logger.info(" ") logger.info(" ") } static async getElement(elementKey: string) { logger.info("elementKey : " + elementKey) const element = N.uiElements.get(elementKey)!.xpath; logger.info("element Locator : " + element) return element } static async getElementStatus(locator: string) { let visibleFlag = false; try { if (locator == null || locator == "null" || locator == undefined) { logger.info("Passed locator is null") } else { logger.info("____________" + new Date().toLocaleString() + "_____________________1") const browser = this.prototype.helpers['WebDriver']; // logger.info("____________" + new Date().toLocaleString() + "_____________________1.1") await browser.waitForElement(locator, 7) await browser.seeElementInDOM(locator) // I.wait(15); // let count = await I.grabNumberOfVisibleElements(locator) // if (count > 0) { visibleFlag = true // } logger.info("____________" + new Date().toLocaleString() + "_____________________2") // visibleFlag = true; // logger.info("____________" + new Date().toLocaleString() + "_____________________3") } } catch (error) { logger.info("not visible after " + 7 + " " + error) visibleFlag = false; } logger.info("element status : : : : " + visibleFlag) return visibleFlag; } static async getLocator(locator: string, locatorType: string) { let locators = locator; switch (locatorType) { case 'xPath': { locators = await N.uiElements.get(locator)!.xpath; break; } case 'cssSelector': { locators = await N.uiElements.get(locator)!.cssSelector; break; } case 'absolutePath': { locators = await N.uiElements.get(locator)!.absolutePath; break; } case 'className': { locators = await N.uiElements.get(locator)!.className; break; } case 'id': { locators = await N.uiElements.get(locator)!.id; break; } case 'label': { locators = await N.uiElements.get(locator)!.label; break; } default: { locators = await N.uiElements.get(locator)!.xpath; break; } } return locators } static async getActualXpath(locator: string) { if (locator.startsWith("/") || locator.startsWith(".") || locator.startsWith("#") || locator.startsWith("{") || locator.startsWith("(")) { return locator; } else { return N.uiElements.get(locator)!.xpath } } static async checkUniqueNess(locator: string) { let flag = false; try { const browser = this.prototype.helpers['WebDriver']; let item_count = await browser.grabNumberOfVisibleElements(locator) console.log(item_count) if (item_count == 1) { flag = true; console.log("class name is unique") } else { console.log("class name is not unique") } } catch (error) { logger.info("class name not found" + error) } console.log(flag) return flag; } //============================================= //===================== PUPPETEER CODE START ===================== // static async getHelper() { let helperr: any; if (helper === webDriver) helperr = this.prototype.helpers[webDriver]; else if (helper === puppeteer) helperr = this.prototype.helpers[puppeteer]; return helperr; } private static async getXYCoordinates(alignment?: object) { const page = this.prototype.helpers["Puppeteer"].page; let object = await page.viewport(); // let width = object["width"] / 2; // let height = object["height"] / 2; let width = 0; let height = 0; // const value = await I.grabElementBoundingRect(locator); // let elementX = value["x"]; // let elementY = value["y"]; // if(elementX > width) width = elementX - width; // else width = width - elementX; // if(elementY > height) height = elementY - height; // else height = height - elementY; if(alignment) { if(alignment["block"]) { let block = alignment["block"]; if(block === "start" || block === "nearest") height = 0; else if(block === "center") height = object["height"] / 2; else if(block === "end") height = object["height"]; } else height = 0; if(alignment["inline"]) { let inline = alignment["inline"]; if(inline === "start" || inline === "nearest") width = 0; else if(inline === "center") width = object["width"] / 2; else if(inline === "end") width = object["width"]; } else width = 0; } else { width = 0; height = 0; } // console.log(`element scroll to coordinates --> ${width}, ${height}`); return [width, height]; } private static async scrollIntoViewWrapper(browser: any, locator: string, alignTop?: any) { if(helper === webDriver) { await browser.scrollIntoView(locator, { behavior: "auto", block: "center", inline: "center" }) } else if(helper === puppeteer) { let arr = await this.getXYCoordinates(alignTop); await I.scrollTo(locator, arr[0], arr[1]); } } }