/** * ************************************************************************* * Copyright (C) 2014 GGA Software Services LLC * <p> * This file may be distributed and/or modified under the terms of the * GNU General Public License version 3 as published by the Free Software * Foundation. * <p> * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * <p> * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses>. * ************************************************************************* */ package com.ggasoftware.uitest.control; import com.ggasoftware.uitest.control.base.annotations.functions.Functions; import com.ggasoftware.uitest.control.base.apiInteract.GetElementModule; import com.ggasoftware.uitest.control.base.logger.LogSettings; import com.ggasoftware.uitest.control.interfaces.base.IElement; import com.ggasoftware.uitest.control.interfaces.common.IButton; import com.ggasoftware.uitest.control.interfaces.common.IText; import com.ggasoftware.uitest.control.new_controls.base.BaseElement; import com.ggasoftware.uitest.control.new_controls.common.Text; import com.ggasoftware.uitest.utils.PropertyReader; import com.ggasoftware.uitest.utils.ReporterNGExt; import com.ggasoftware.uitest.utils.Timer; import org.openqa.selenium.interactions.Action; import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import java.lang.reflect.Field; import java.util.Collection; import java.util.List; import java.util.Properties; import static com.ggasoftware.uitest.control.base.asserter.testNG.Assert.exception; import static com.ggasoftware.uitest.control.base.logger.enums.LogInfoTypes.BUSINESS; import static com.ggasoftware.uitest.control.base.logger.enums.LogLevels.DEBUG; import static com.ggasoftware.uitest.utils.LinqUtils.first; import static com.ggasoftware.uitest.utils.LinqUtils.select; import static com.ggasoftware.uitest.utils.ReflectionUtils.getFieldValue; import static com.ggasoftware.uitest.utils.ReflectionUtils.getFields; import static com.ggasoftware.uitest.utils.ReporterNG.logTechnical; import static com.ggasoftware.uitest.utils.ReporterNGExt.*; import static com.ggasoftware.uitest.utils.TestBaseWebDriver.logFindElementLocator; import static com.ggasoftware.uitest.utils.TestBaseWebDriver.takePassedScreenshot; import static com.ggasoftware.uitest.utils.Timer.alwaysDoneAction; import static com.ggasoftware.uitest.utils.Timer.getResultAction; import static com.ggasoftware.uitest.utils.WebDriverWrapper.*; import static java.lang.String.format; /** * Base Element control implementation * * @author Alexeenko Yan * @author Belin Yury * @author Belousov Andrey * @author Shubin Konstantin * @author Zharov Alexandr */ public class Element<ParentPanel> extends BaseElement<ParentPanel> implements IElement<ParentPanel> { /** * Contains name of the element used for locating its parameters in properties file */ protected final Properties properties = new Properties(); { PropertyReader.getProperties(properties, this.getClass().getName()); String panelLocator = getProperty("main"); if (panelLocator != null) { this.locator = panelLocator; avatar = new GetElementModule(getByLocator(), this); } } protected Element() { } /** * Initializes element with given locator. Locates own properties of the element by class name, takes given locator and tries * to initialize. * * @param name - Element name * @param locator - start it with locator type "id=", "css=", "xpath=" and etc. Locator without type is assigned to xpath * @param panel - Parent panel instance */ public Element(String name, String locator, ParentPanel panel) { super(name, locator, panel); } public Element(String name, By byLocator) { super(name, byLocator); } public Element(By byLocator) { super(byLocator); } public static <T extends IElement> T copy(T element, By newLocator) { try { T result = (T) element.getClass().newInstance(); result.setAvatar(newLocator, element.getAvatar()); return result; } catch (Exception | AssertionError ex) { throw exception("Can't copy element: " + element); } } /** * Searches for the property with the specified key in this property list. * If the key is not found in this property list, the default property list, * and its defaults, recursively, are then checked. The method returns * <code>null</code> if the property is not found. * * @param key the property key. * @return the value in this property list with the specified key value. */ public String getProperty(String key) { return properties.getProperty(key); } /** * Sets locator for the element * * @param elementLocator - Locator of the element. Start it with locator type "id=", "css=", "xpath=" and etc. */ protected void setLocator(String elementLocator) { this.locator = elementLocator; } /** * Sets locator for the element * * @param parentPanel - Locator of the element. Start it with locator type "id=", "css=", "xpath=" and etc. */ protected void setParent(ParentPanel parentPanel) { this.parent = parentPanel; } public boolean waitDisplayed() { return waitDisplayed(TIMEOUT); } public boolean waitDisplayed(int seconds) { return doJActionResult("Wait element appear during '%s' seconds", () -> { setWaitTimeout(seconds); boolean result = new Timer(seconds * 1000).wait(() -> avatar.getElement().isDisplayed()); setWaitTimeout(TIMEOUT); return result; }); } public boolean waitVanished() { return waitDisplayed(TIMEOUT); } public boolean waitVanished(int seconds) { return doJActionResult("Wait element disappear during '%s' seconds", () -> { setWaitTimeout(100); boolean result = new Timer(seconds * 1000).wait(() -> !(avatar.getElement().isDisplayed())); setWaitTimeout(TIMEOUT); return result; }); } public WebElement getWebElement() { return doJActionResult("Get web element " + this.toString(), avatar::getElement, new LogSettings(DEBUG, BUSINESS)); } public WebElement getWebElement(int seconds) { setTimeout(seconds); WebElement result = doJActionResult("Get web element " + this.toString(), avatar::getElement, new LogSettings(DEBUG, BUSINESS)); setTimeout(TIMEOUT); return result; } protected Button getButton(Functions funcName) { List<Field> fields = getFields(this, IButton.class); if (fields.size() == 1) return (Button) getFieldValue(fields.get(0), this); Collection<Button> buttons = select(fields, f -> (Button) getFieldValue(f, this)); Button button = first(buttons, b -> b.function.equals(funcName)); if (button == null) { throw exception(format("Can't find button '%s' for element '%s'", funcName, toString())); } return button; } protected Text getTextElement() { Field textField = first(getClass().getDeclaredFields(), f -> (f.getType() == Text.class) || (f.getType() == IText.class)); if (textField != null) return (Text) getFieldValue(textField, this); throw exception(format("Can't find Text element '%s'", toString())); } // Common functions protected void clickActionM() { getWebElement().click(); } public ParentPanel click() { doJAction("Click on element", this::clickActionM); return parent; } /** * A convenience method that performs click at the location of the source element * * @param xOffset - horizontal move offset. * @param yOffset - vertical move offset. * @return Parent instance */ public ParentPanel clickBy(int xOffset, int yOffset) { doJAction(format("click element: horizontal move offset- %dpx; vertical move offset- %dpx", xOffset, yOffset), () -> { Actions builder = new Actions(getDriver()); Action click = builder.moveToElement(getWebElement(), xOffset, yOffset).click().build(); click.perform(); }); return parent; } /** * Replace each substring of this string "$VALUE" to [value] in [str] * * @param str - input string for replacement * @param value -The replacement sequence of char values * @return The resulting string */ protected String insertValue(String str, String value) { return str.replace("$VALUE", value); } protected String insertValues(String str, String[] values) { int i = 0; String result = str; for (String value : values) result = result.replace("$VALUE" + i++, value); return result; } /** * Click on the Element(WebElement) by JS * * @return Parent instance */ public ParentPanel clickJS() { doJAction("clickJS", () -> jsExecutor().executeScript("arguments[0].click();", getWebElement())); return parent; } /** * Serialize Form by JS * * @return Serialize result */ public String serializeForm() { return doJActionResult("serializeForm", () -> (String) jsExecutor().executeScript("return $(arguments[0]).serialize();", getWebElement())); } /** * Mouse Over on the Element(WebElement) by JS * * @return Parent instance */ public ParentPanel mouseOverJS() { doJAction("mouseOverJS", () -> { String script = "var evt = document.createEvent('MouseEvents');" + "evt.initMouseEvent('mouseover',true, true, window, 500, 100, 0, 0, 0, false, false, false, false, 0, null);" + "arguments[0].dispatchEvent(evt);"; jsExecutor().executeScript(script, getWebElement()); }); return parent; } /** * Click on the Element(WebElement) with pressed CTRL key * * @return Parent instance */ public ParentPanel ctrlClick() { doJAction("ctrlClick", () -> new Actions(getDriver()).keyDown(Keys.CONTROL) .moveToElement(getWebElement()) .click() .keyUp(Keys.CONTROL) .perform()); return parent; } /** * Focus window and Click on the Element(WebElement) * * @return Parent instance */ public ParentPanel focusWindowAndClick() { logAction(this, getParentClassName(), "focusWindowAndClick"); getDriver().switchTo().window(""); getWebElement().click(); return parent; } /** * Performs a double-click at the current mouse location. * * @return Parent instance */ public ParentPanel doubleClick() { getWebElement().getSize(); //for scroll to object logAction(this, getParentClassName(), "doubleClick"); alwaysDoneAction(() -> { Actions builder = new Actions(getDriver()); builder.doubleClick(); }); return parent; } /** * Performs a right-click at the current mouse location. * * @return Parent instance */ public ParentPanel rightClick() { getWebElement().getSize(); //for scroll to object logAction(this, getParentClassName(), "rightClick"); Actions builder = new Actions(getDriver()); builder.contextClick(getWebElement()).perform(); return parent; } /** * Clicks in the middle of the given element. Equivalent to: * Actions.moveToElement(onElement).click() * * @return Parent instance */ public ParentPanel clickAction() { getWebElement().getSize(); //for scroll to object logAction(this, getParentClassName(), "clickAction"); alwaysDoneAction(() -> { Actions builder = new Actions(getDriver()); builder.click(getWebElement()).perform(); }); return parent; } public String getSimpleClassName() { return getClass().getSimpleName(); } /** * Mouse Over on the the given element. * * @return Parent instance */ public ParentPanel mouseOver() { getWebElement().getSize(); //for scroll to object logAction(this, getParentClassName(), "mouseOver"); Actions builder = new Actions(getDriver()); builder.moveToElement(getWebElement()).build().perform(); return parent; } /** * Focus on the Element(WebElement) * * @return Parent instance */ public ParentPanel focus() { Dimension size = getWebElement().getSize(); //for scroll to object logAction(this, getParentClassName(), "focus"); Actions builder = new Actions(getDriver()); org.openqa.selenium.interactions.Action focus = builder.moveToElement(getWebElement(), size.width / 2, size.height / 2).build(); focus.perform(); return parent; } /** * Click on the Element(WebElement) until expectedElement is NOT DISPLAYED * * @param expectedElement - expected Element * @param tryCount - number of count for click * @return Parent instance */ public ParentPanel clickWhileObjectNotDisplayed(Element expectedElement, int tryCount) { logAction(this, getParentClassName(), format("clickWhileObjectNotDisplayed: element locator '%s', element name '%s'", expectedElement.locator, expectedElement.getName())); int i = 0; while (!(expectedElement.isDisplayed())) { if (isDisplayed()) { getWebElement().click(); } else { break; } i++; if (i >= tryCount) { break; } } return parent; } /** * Click on the Element(WebElement) until expectedElement exists * * @param expectedElement - expected Element * @param tryCount - number of count for click * @return Parent instance */ public ParentPanel clickWhileObjectNotExist(Element expectedElement, int tryCount) { logAction(this, getParentClassName(), format("clickWhileObjectNotExist: element locator '%s', element name '%s'", expectedElement.locator, expectedElement.getName())); int i = 0; while (!(expectedElement.isExists())) { getWebElement().click(); i++; if (i >= tryCount) { break; } } return parent; } /** * Click on the Element(WebElement) until expectedElement is displayed * * @param expectedElement - expected Element * @param tryCount - number of count for click * @return Parent instance */ public ParentPanel clickWhileObjectIsDisplayed(Element expectedElement, int tryCount) { logAction(this, getParentClassName(), format("clickWhileObjectExist: element locator '%s', element name '%s'", expectedElement.locator, expectedElement.getName())); int i = 0; while ((expectedElement.isDisplayed())) { getWebElement().click(); i++; if (i >= tryCount) { break; } } return parent; } /** * Use Clickable elements instead of Element type * Use this method to simulate typing into an element, which may set its value. * * @param keysToSend - CharSequence to send * @return Parent instance */ public ParentPanel sendKeys(CharSequence... keysToSend) { doJAction(format("sendKeys: %s", keysToSend), () -> { getDriver().switchTo().activeElement(); getWebElement().sendKeys(keysToSend); }); return parent; } /** * Use this method to simulate typing into an element with secure log, which may set its value. * * @param keysToSend - CharSequence to send * @return Parent instance */ public ParentPanel sendKeysSecure(CharSequence... keysToSend) { logAction(this, getParentClassName(), "sendKeysSecure"); alwaysDoneAction(() -> { getDriver().switchTo().activeElement(); getWebElement().sendKeys(keysToSend); }); return parent; } /** * Use this method to simulate send keys to the element. * * @param sendKeys - e.g. sendKeys(Keys.ARROW_DOWN) * @return Parent instance */ protected ParentPanel sendKeys(Keys sendKeys) { logAction(this, getParentClassName(), format("sendKeys - %s", sendKeys)); alwaysDoneAction(() -> { getDriver().switchTo().activeElement(); getWebElement().sendKeys(sendKeys); }); return parent; } /** * Is this element exists (on the web page) or not? * * @return true if we can find Element on the web page, otherwise false */ public boolean isExists() { if (logFindElementLocator) { logTechnical(format("Find Elements '%s'", locator)); } return !getDriver().findElements(avatar.byLocator).isEmpty(); } /** * Is this element exists (on the web page) or not? * * @param seconds to wait until element become existed. * @return true if we can find Element on the web page, otherwise false */ public boolean isExists(int seconds) { setTimeout(seconds); boolean found = isExists(); setTimeout(TIMEOUT); return found; } /** * Is this element vanished from the web page * * @return true if element not exists or not displayed at the page */ public boolean isVanished() { setTimeout(0); boolean result = !isExists(0) || !(getWebElement().isDisplayed()); ; setTimeout(TIMEOUT); return result; } /** * Is this element displayed or not? This method avoids the problem of having to parse an * element's "style" attribute. * * @return Whether or not the element is displayed */ public boolean isDisplayed() { return isDisplayed(TIMEOUT); } /** * Is this element displayed or not? This method avoids the problem of having to parse an * element's "style" attribute. * * @param seconds to wait until element become visible or undiscovered. * @return Whether or not the element is displayed */ public boolean isDisplayed(int seconds) { setTimeout(seconds); boolean result = isExists(seconds) && getWebElement().isDisplayed(); setTimeout(TIMEOUT); return result; } /** * Is the element currently enabled or not? This will generally return true for everything but * disabled input elements. * * @return True if the element is enabled, false otherwise. */ public boolean isEnabled() { return isEnabled(TIMEOUT); } /** * Is the element currently enabled or not? This will generally return true for everything but * disabled input elements. * * @param seconds to wait until element become enable or undiscovered. * @return True if the element is enabled, false otherwise. */ public boolean isEnabled(int seconds) { setTimeout(seconds); boolean result = isExists(seconds) && getWebElement().isEnabled(); setTimeout(TIMEOUT); return result; } /** * Get the visible (i.e. not hidden by CSS) innerText of this element, including sub-elements, * without any leading or trailing whitespace. * * @return The innerText of this element. */ public String getText() { String result = getResultAction(() -> getWebElement().getText()); logAction(this, getParentClassName(), format("got ext : %s", result)); return result; } /** * Get the visible (i.e. not hidden by CSS) innerText of this element, excluding sub-elements, * without any leading or trailing whitespace. * * @return The innerText of this element. */ public String getElementText() { int l = 0; for (WebElement webElement : getChild()) { l = +webElement.getText().length(); } return (String) logGetter(this, getParentClassName(), "element text", getWebElement().getText().substring(l)); } /** * !!! Use waitAttribute(String name, String value) instead * Get the value of a the given attribute of the element. Will return the current value, even if * this has been modified after the page has been loaded. * * @param sName The name of the attribute. * @return The attribute's current value or null if the value is not set. */ public String getAttribute(String sName) { return (String) logGetter(this, getParentClassName(), sName, getWebElement().getAttribute(sName)); } public boolean waitAttribute(String name, String value) { return doJActionResult(format("Wait attribute %s='%s'", name, value), () -> getWebElement().getAttribute(name).equals(value)); } public boolean waitAttributeChanged(String name, String value) { return doJActionResult(format("Wait attribute %s='%s' changed", name, value), () -> !getWebElement().getAttribute(name).equals(value)); } /** * Set the value of a the given attribute of the element by JS. * * @param attribute The name of the attribute. * @param value value The value of the attribute. * @return Parent instance */ public ParentPanel setAttributeJS(String attribute, String value) { ((JavascriptExecutor) getDriver()).executeScript(format("arguments[0].setAttribute('%s',arguments[1]);", attribute), getWebElement(), value); return parent; } /** * Get the value of a given CSS property. This is probably not going to return what you expect it * to unless you've already had a look at the element using something like firebug. Seriously, * even then you'll be lucky for this to work cross-browser. Colour values should be returned as * hex strings, so, for example if the "background-color" property is set as "green" in the HTML * source, the returned value will be "#008000" * * @param name - css name * @return The current, computed value of the property. */ public String getCssValue(String name) { return (String) logGetter(this, getParentClassName(), name, getWebElement().getCssValue(name)); } /** * Where on the page is the top left-hand corner of the rendered element? * We can use also: * - getLocation().x or getLocation().getX * - getLocation().y or getLocation().getY * * @return A point, containing the location of the top left-hand corner of the element */ public Point getLocation() { return (Point) logGetter(this, getParentClassName(), "Location", getWebElement().getLocation()); } /** * What is the width and height of the rendered element? * We can use also: * - getWebElement().getSize().width or getWebElement().getSize().getWidth() * - getWebElement().getSize().height or getWebElement().getSize().getHeight() * * @return The size of the element on the page. */ public Dimension getSize() { return (Dimension) logGetter(this, getParentClassName(), "Dimension", getWebElement().getSize()); } /** * Get the tag name of this element. <b>Not</b> the value of the name attribute: will return * <code>"input"</code> for the element <code><input name="foo" /></code>. * * @return The tag name of this element. */ public String getTagName() { return (String) logGetter(this, getParentClassName(), "TagName", getWebElement().getTagName()); } /** * Has child element with specified tag * * @param tagName Tag name * @return Has child or not */ public boolean hasChildByTag(String tagName) { return (Boolean) logGetter(this, getParentClassName(), "HasChildByTag", !getWebElement().findElements(By.tagName(tagName)).isEmpty()); } /** * Has child element * * @return Has child or not */ public boolean hasChild() { return (Boolean) logGetter(this, getParentClassName(), "HasChild", !getWebElement().findElements(By.xpath(".//*")).isEmpty()); } /** * Get child elements * * @return Has child or not */ public List<WebElement> getChild() { if (logFindElementLocator) { logTechnical(format("Get Child Web Elements '%s'", locator)); } return getWebElement().findElements(By.xpath(".//*")); } /** * Get full xpath string * * @return Xpath of the element */ public String getXPath() { String sLocator = locator.replaceAll("\\w*=(.*)", "$1").trim(); String sType = locator.replaceAll("(\\w*)=.*", "$1").trim(); switch (sType) { case "css": return ""; case "id": return format("//*[@id=\"%s\"]", sLocator); case "link": return format("//*[@link=\"%s\"]", sLocator); case "xpath": return format("%s", sLocator); case "text": return format("//*[contains(text(), '%s')]", sLocator); case "name": return format("//*[@name=\"%s\"]", sLocator); default: return locator; } } /** * Select some area (mouse from point(x1, y1) to point(x2, y2) in element) * * @param x1 - x1 coordinate of element * @param y1 - y1 coordinate of element * @param x2 - x2 coordinate of element * @param y2 - y2 coordinate of element * @return Parent instance */ public ParentPanel selectArea(int x1, int y1, int x2, int y2) { logAction(this, getParentClassName(), format("Select area: from %d,%d;to %d,%d", x1, y1, x2, y2)); WebElement element = getWebElement(); new Actions(getDriver()).moveToElement(element, x1, y1) .clickAndHold() .moveToElement(element, x2, y2) .release() .build() .perform(); return parent; } /** * A convenience method that performs click-and-hold at the location of the source element, moves by a given offset, then releases the mouse. * * @param xOffset - horizontal move offset. * @param yOffset - vertical move offset. * @return Parent instance */ public ParentPanel dragAndDropBy(int xOffset, int yOffset) { logAction(this, getParentClassName(), format("Drag and drop element: horizontal move offset - %dpx; vertical move offset - %dpx", xOffset, yOffset)); Actions builder = new Actions(getDriver()); Action dragAndDropBy = builder.dragAndDropBy(getWebElement(), xOffset, yOffset).build(); dragAndDropBy.perform(); return parent; } /** * Wait until element exists. * * @param timeoutSec seconds to wait until element exists. * @param checkCondition log assert for expected conditions. * @return Parent instance */ public ParentPanel waitForExists(int timeoutSec, boolean checkCondition) { boolean isExists; logAction(this, getParentClassName(), format("waitForExists: %s", locator)); long start = System.currentTimeMillis() / 1000; WebDriverWait wait = (WebDriverWait) new WebDriverWait(getDriver(), timeoutSec) .ignoring(StaleElementReferenceException.class); setTimeout(1); try { wait.until(ExpectedConditions.presenceOfElementLocated(avatar.byLocator)); isExists = true; } catch (TimeoutException e) { logTechnical(format("waitForExists: [ %s ] during: [ %d ] sec ", locator, System.currentTimeMillis() / 1000 - start)); isExists = false; } setTimeout(TIMEOUT); if (checkCondition) { logAssertTrue(BUSINESS_LEVEL, isExists, format("waitForExists - '%s' should exist", getName()), takePassedScreenshot); } return parent; } /** * Wait until element exists. * * @param timeoutSec seconds to wait until element exists. * @return Parent instance */ public ParentPanel waitForExists(int timeoutSec) { return waitForExists(timeoutSec, CHECKCONDITION); } /** * Wait until element exists. * * @return Parent instance */ public ParentPanel waitForExists() { return waitForExists(TIMEOUT); } /** * Wait until element exists. * * @param checkCondition log assert for expected conditions. * @return Parent instance */ public ParentPanel waitForExists(boolean checkCondition) { return waitForExists(TIMEOUT, checkCondition); } /** * Wait until element is displayed. * * @param timeoutSec seconds to wait until element is displayed. * @param checkCondition log assert for expected conditions. * @return Parent instance */ private ParentPanel waitForDisplayed(int timeoutSec, boolean checkCondition) { boolean isDisplayed; logAction(this, getParentClassName(), format("waitForDisplayed: %s", locator)); long start = System.currentTimeMillis() / 1000; WebDriverWait wait = (WebDriverWait) new WebDriverWait(getDriver(), timeoutSec) .ignoring(StaleElementReferenceException.class); setTimeout(1); try { wait.until(ExpectedConditions.visibilityOfElementLocated(avatar.byLocator)); isDisplayed = true; } catch (TimeoutException e) { logTechnical(format("waitForDisplayed: [ %s ] during: [ %d ] sec ", locator, System.currentTimeMillis() / 1000 - start)); isDisplayed = false; } setTimeout(TIMEOUT); if (checkCondition) { logAssertTrue(BUSINESS_LEVEL, isDisplayed, format("waitForDisplayed - '%s' should be displayed", getName()), takePassedScreenshot); } return parent; } /** * Wait until element is displayed. * * @param timeoutSec seconds to wait until element is displayed. * @return Parent instance */ public ParentPanel waitForDisplayed(int timeoutSec) { return waitForDisplayed(timeoutSec, CHECKCONDITION); } /** * Wait until element is displayed. * * @return Parent instance */ public ParentPanel waitForDisplayed() { return waitForDisplayed(TIMEOUT); } /** * Wait until element is displayed. * * @param checkCondition log assert for expected conditions. * @return Parent instance */ public ParentPanel waitForDisplayed(boolean checkCondition) { return waitForDisplayed(TIMEOUT, checkCondition); } /** * Wait until element is vanished. * * @return Parent instance */ public ParentPanel waitForElementToVanish() { return waitForElementToVanish(TIMEOUT, CHECKCONDITION); } /** * Wait until element is vanished. * * @param timeoutSec - the maximum time to wait in seconds (until element become invisible or disappeared) * @return Parent instance */ public ParentPanel waitForElementToVanish(int timeoutSec) { return waitForElementToVanish(timeoutSec, CHECKCONDITION); } /** * Wait until element is vanished. * * @param checkCondition log assert for expected conditions. * @return Parent instance */ public ParentPanel waitForElementToVanish(boolean checkCondition) { return waitForElementToVanish(TIMEOUT, CHECKCONDITION); } /** * Wait until element is vanished. * * @param timeoutSec - the maximum time to wait in seconds (until element become invisible or disappeared) * @param checkCondition log assert for expected conditions. * @return Parent instance */ public ParentPanel waitForElementToVanish(int timeoutSec, boolean checkCondition) { boolean isVanished; logAction(this, getParentClassName(), format("waitForElementToVanish: %s", locator)); long start = System.currentTimeMillis() / 1000; WebDriverWait wait = (WebDriverWait) new WebDriverWait(getDriver(), timeoutSec) .ignoring(StaleElementReferenceException.class, NoSuchElementException.class); setTimeout(1); try { isVanished = wait.until(ExpectedConditions.invisibilityOfElementLocated(avatar.byLocator)); } catch (TimeoutException e) { logTechnical(format("waitForElementToVanish: [ %s ] during: [ %d ] sec ", locator, System.currentTimeMillis() / 1000 - start)); isVanished = false; } setTimeout(TIMEOUT); if (checkCondition) { logAssertTrue(BUSINESS_LEVEL, isVanished, format("waitForElementToVanish - '%s' should be vanished", getName()), takePassedScreenshot); } return parent; } /** * Wait until element has a text. * * @param text Text of Element * @return Parent instance */ public ParentPanel waitForText(final String text) { return waitForText(text, TIMEOUT, CHECKCONDITION); } /** * Wait until element has a text. * * @param text Text of Element * @param timeoutSec seconds to wait until element has a text * @return Parent instance */ public ParentPanel waitForText(final String text, final int timeoutSec) { return waitForText(text, timeoutSec, CHECKCONDITION); } /** * Wait until element has a text. * * @param text Text of Element * @param timeoutSec seconds to wait until element has a text * @param checkCondition log assert for expected conditions. * @return Parent instance */ public ParentPanel waitForText(final String text, final int timeoutSec, final boolean checkCondition) { boolean isPresent; logAction(this, getParentClassName(), format("waitForText[%s]: %s", text, locator)); long start = System.currentTimeMillis() / 1000; WebDriverWait wait = (WebDriverWait) new WebDriverWait(getDriver(), timeoutSec) .ignoring(StaleElementReferenceException.class); try { wait.until(ExpectedConditions.textToBePresentInElementLocated(avatar.byLocator, text)); getText(); isPresent = wait.until( new ExpectedCondition<Boolean>() { @Override public Boolean apply(WebDriver driver) { return getDriver().findElement(avatar.byLocator).getText().equals(text); } } ); } catch (TimeoutException e) { logTechnical(format("waitForText: [ %s ] during: [ %d ] sec ", locator, System.currentTimeMillis() / 1000 - start)); isPresent = false; } if (checkCondition) { logAssertTrue(BUSINESS_LEVEL, isPresent, format("waitForText - '%s' should has a text '%s'", getName(), text), takePassedScreenshot); } return parent; } /** * Wait until element contains a text. * * @param text Text of Element * @return Parent instance */ public ParentPanel waitForTextContains(final String text) { return waitForTextContains(text, TIMEOUT, CHECKCONDITION); } /** * Wait until element contains a text. * * @param text Text of Element * @param timeoutSec seconds to wait until element contains a text * @return Parent instance */ public ParentPanel waitForTextContains(final String text, final int timeoutSec) { return waitForTextContains(text, timeoutSec, CHECKCONDITION); } /** * Wait until element contains a text. * * @param text Text of Element * @param timeoutSec seconds to wait until element contains a text * @param checkCondition log assert for expected conditions. * @return Parent instance */ public ParentPanel waitForTextContains(final String text, final int timeoutSec, final boolean checkCondition) { boolean isPresent; logAction(this, getParentClassName(), format("waitForTextContains[%s]: %s", text, locator)); long start = System.currentTimeMillis() / 1000; final WebDriverWait wait = (WebDriverWait) new WebDriverWait(getDriver(), timeoutSec) .ignoring(StaleElementReferenceException.class); try { isPresent = wait.until(ExpectedConditions.textToBePresentInElementLocated(avatar.byLocator, text)); } catch (TimeoutException e) { logTechnical(format("waitForTextContains: [ %s ] during: [ %d ] sec ", locator, System.currentTimeMillis() / 1000 - start)); isPresent = false; } if (checkCondition) { logAssertTrue(BUSINESS_LEVEL, isPresent, format("waitForTextContains - '%s' should has a text contains '%s'", getName(), text), takePassedScreenshot); } return parent; } /** * Wait until element is changed text. * * @param text before change * @return Parent instance */ public ParentPanel waitForTextChanged(final String text) { return waitForTextChanged(text, TIMEOUT, CHECKCONDITION); } /** * Wait until element is changed text. * * @param text before change * @param timeoutSec seconds to wait until element is changed text * @return Parent instance */ public ParentPanel waitForTextChanged(final String text, final int timeoutSec) { return waitForTextChanged(text, timeoutSec, CHECKCONDITION); } /** * Wait until element is changed text. * * @param text before change * @param timeoutSec seconds to wait until element is changed text * @param checkCondition log assert for expected conditions. * @return Parent instance */ public ParentPanel waitForTextChanged(final String text, final int timeoutSec, final boolean checkCondition) { boolean isChanged; logAction(this, getParentClassName(), format("waitForTextChanged[%s]: %s", text, locator)); long start = System.currentTimeMillis() / 1000; WebDriverWait wait = (WebDriverWait) new WebDriverWait(getDriver(), timeoutSec) .ignoring(StaleElementReferenceException.class); try { isChanged = wait.until(ExpectedConditions.not(ExpectedConditions.textToBePresentInElementLocated(avatar.byLocator, text))); } catch (TimeoutException e) { logTechnical(format("waitForTextChanged: [ %s ] during: [ %d ] sec ", locator, System.currentTimeMillis() / 1000 - start)); isChanged = false; } if (checkCondition) { logAssertTrue(BUSINESS_LEVEL, isChanged, format("waitForTextChanged - '%s' text '%s' should be changed", getName(), text), takePassedScreenshot); } return parent; } /** * Wait until element has a 'value' attribute. * * @param value 'Value' Attribute of Element * @return Parent instance */ public ParentPanel waitForValue(final String value) { return waitForText(value, TIMEOUT, CHECKCONDITION); } /** * Wait until element has a 'value' attribute. * * @param value 'Value' Attribute of Element * @param timeoutSec seconds to wait until element has a 'value' attribute * @return Parent instance */ public ParentPanel waitForValue(final String value, int timeoutSec) { return waitForText(value, timeoutSec, CHECKCONDITION); } /** * Wait until element has a 'value' attribute. * * @param value 'Value' Attribute of Element * @param timeoutSec seconds to wait until element has a 'value' attribute * @param checkCondition log assert for expected conditions. * @return Parent instance */ public ParentPanel waitForValue(final String value, final int timeoutSec, final boolean checkCondition) { boolean isPresent; logAction(this, getParentClassName(), format("waitForValueAttribute[%s]: %s", value, locator)); long start = System.currentTimeMillis() / 1000; WebDriverWait wait = (WebDriverWait) new WebDriverWait(getDriver(), timeoutSec) .ignoring(StaleElementReferenceException.class); try { isPresent = wait.until(ExpectedConditions.textToBePresentInElementValue(avatar.byLocator, value)); } catch (TimeoutException e) { logTechnical(format("waitForValueAttribute: [ %s ] during: [ %d ] sec ", locator, System.currentTimeMillis() / 1000 - start)); isPresent = false; } if (checkCondition) { logAssertTrue(BUSINESS_LEVEL, isPresent, format("waitForValueAttribute - '%s' should has a value attribute '%s'", getName(), value), takePassedScreenshot); } return parent; } /** * !!! Use waitAttribute(String name, String value)* * Wait until element is changed the attribute. * * @param attribute for watching * @param value of attribute before change * @param timeoutSec seconds to wait until element is changed attribute * @return Parent instance */ public ParentPanel waitForAttributeChanged(final String attribute, final String value, final int timeoutSec) { return waitForAttributeChanged(attribute, value, timeoutSec, true); } /** * !!! Use waitAttribute(String name, String value) * Wait until element is changed the attribute. * * @param attribute for watching * @param value of attribute before change * @param timeoutSec seconds to wait until element is changed attribute * @param checkCondition log assert for expected conditions. * @return Parent instance */ public ParentPanel waitForAttributeChanged(final String attribute, final String value, final int timeoutSec, final boolean checkCondition) { setTimeout(timeoutSec); boolean result = new Timer(timeoutSec).wait(() -> !getWebElement(timeoutSec).getAttribute(attribute).equals(value)); logAssertTrue(BUSINESS_LEVEL, result, format("waitForAttributeChanged - '%s' attribute '%s' value '%s' should be changed", getName(), attribute, value), takePassedScreenshot); setTimeout(TIMEOUT); if (checkCondition) { logAssertTrue(ReporterNGExt.BUSINESS_LEVEL, result, format("waitForAttributeChanged - '%s' attribute '%s' value '%s' should be changed", name, attribute, value), takePassedScreenshot); } return parent; } /** * Firstly :Wait until element exists, then: Wait until element is vanished. * * @param checkCondition log assert for expected conditions. * @return Parent instance */ public ParentPanel waitForExistsThenVanish(final boolean checkCondition) { logAction(this, getParentClassName(), format("waitForExistsThenVanish:%s", locator)); waitForExists(checkCondition); waitForElementToVanish(checkCondition); return parent; } /** * Firstly :Wait until element exists, then: Wait until element is vanished. * * @return Parent instance */ public ParentPanel waitForExistsThenVanish() { logAction(this, getParentClassName(), format("waitForExistsThenVanish:%s", locator)); waitForExists(); waitForElementToVanish(); return parent; } /** * Get visible WebElement with Element locator. * * @return WebElement */ public WebElement getVisibleWebElement() { Elements elements = new Elements<>(getName(), locator, parent); return elements.getVisibleWebElement(); } /** * Wait until element is clickable and click at it. * * @param timeoutSec seconds to wait until element become clickable. * @return Parent instance */ public ParentPanel waitForClickableAndClick(final int timeoutSec) { boolean isClicked; logAction(this, getParentClassName(), format("waitForClickable: %s", locator)); long start = System.currentTimeMillis() / 1000; WebDriverWait wait = (WebDriverWait) new WebDriverWait(getDriver(), timeoutSec) .ignoring(StaleElementReferenceException.class); try { wait.until(ExpectedConditions.elementToBeClickable(avatar.byLocator)); isClicked = wait.until( new ExpectedCondition<Boolean>() { @Override public Boolean apply(WebDriver driver) { try { setTimeout(timeoutSec); getWebElement().click(); setTimeout(TIMEOUT); return true; } catch (Exception e) { return false; } } } ); } catch (TimeoutException e) { logTechnical(format("waitForClickable: [ %s ] during: [ %d ] sec ", locator, System.currentTimeMillis() / 1000 - start)); isClicked = false; } logAssertTrue(BUSINESS_LEVEL, isClicked, format("waitForClickableAndClick: '%s' was clickable and click at it", getName()), takePassedScreenshot); return parent; } /** * Wait until Expected Condition. * * @param condition - Expected Condition * @return Parent instance */ public ParentPanel waitForExpectedConditions(final ExpectedCondition<Boolean> condition) { return waitForExpectedConditions(condition, TIMEOUT, CHECKCONDITION); } /** * Wait until Expected Condition. * * @param condition - Expected Condition * @param timeoutSec - the maximum time to wait in seconds * @return Parent instance */ public ParentPanel waitForExpectedConditions(final ExpectedCondition<Boolean> condition, final int timeoutSec) { return waitForExpectedConditions(condition, timeoutSec, CHECKCONDITION); } /** * Wait until Expected Condition. * * @param condition - Expected Condition * @param timeoutSec - the maximum time to wait in seconds * @param checkCondition log assert for expected conditions. * @return Parent instance */ public ParentPanel waitForExpectedConditions(final ExpectedCondition<Boolean> condition, final int timeoutSec, final boolean checkCondition) { boolean isTrue; logAction(this, getParentClassName(), format("waitForExpectedCondition[%s}: %s", condition, locator)); long start = System.currentTimeMillis() / 1000; WebDriverWait wait = (WebDriverWait) new WebDriverWait(getDriver(), timeoutSec) .ignoring(StaleElementReferenceException.class); setTimeout(1); try { wait.until(condition); isTrue = false; } catch (TimeoutException e) { logTechnical(format("waitForExpectedCondition: [ %s ] during: [ %d ] sec ", locator, System.currentTimeMillis() / 1000 - start)); isTrue = true; } setTimeout(TIMEOUT); if (checkCondition) { logAssertFalse(BUSINESS_LEVEL, isTrue, format("waitForExpectedCondition - '%s'", condition), takePassedScreenshot); } return parent; } }