INSTANCE = new ThreadLocal<>();
protected FluentElementActions() {
}
public synchronized static FluentElementActions getInstance() {
JavaScriptWaitManager.waitForLazyLoading();
if (INSTANCE.get() == null) {
INSTANCE.set(new FluentElementActions());
}
return INSTANCE.get();
}
/**
* This is a convenience method to be able to call TouchActions Actions for
* touch-enabled devices from within the regular Element Actions Class.
*
* Sample use would look like this:
* ElementActions.performTouchAction().tap(driver, loginButton);
*
* @return a TouchActions object capable of performing actions on touch-enabled devices
*/
public TouchActions performTouchAction() {
return new TouchActions();
}
public AlertActions performAlertAction() {
return new AlertActions();
}
public FluentBrowserActions performBrowserAction() {
return FluentBrowserActions.getInstance();
}
public SikuliActions performSikuliAction() {
return new SikuliActions();
}
public SikuliActions performSikuliAction(App applicationWindow) {
return new SikuliActions(applicationWindow);
}
public TouchActions touch() {
return new TouchActions();
}
public AlertActions alert() {
return new AlertActions();
}
public FluentBrowserActions browser() {
return FluentBrowserActions.getInstance();
}
public SikuliActions sikulix() {
return new SikuliActions();
}
public SikuliActions sikulix(App applicationWindow) {
return new SikuliActions(applicationWindow);
}
public FluentElementActions and() {
return this;
}
public WebDriverElementValidationsBuilder assertThat(By elementLocator) {
return new WizardHelpers.WebDriverAssertions().element(elementLocator);
}
public WebDriverElementValidationsBuilder verifyThat(By elementLocator) {
return new WizardHelpers.WebDriverVerifications().element(elementLocator);
}
public int getElementsCount(By elementLocator) {
return ElementActionsHelper.getElementsCount(DriverFactoryHelper.getDriver().get(), elementLocator);
}
/**
* Retrieves the selected text from the target drop-down list element and returns it as a string value.
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @return the selected text of the target webElement
*/
public String getSelectedText(By elementLocator) {
try {
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), elementLocator);
StringBuilder elementSelectedText = new StringBuilder();
try {
new Select(((WebElement) ElementActionsHelper.identifyUniqueElementIgnoringVisibility(DriverFactoryHelper.getDriver().get(), elementLocator).get(1))).getAllSelectedOptions().forEach(selectedOption -> elementSelectedText.append(selectedOption.getText()));
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), elementSelectedText.toString().trim(), null, elementName);
return elementSelectedText.toString().trim();
} catch (UnexpectedTagNameException rootCauseException) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, rootCauseException);
return null;
}
} catch (Throwable throwable) {
// has to be throwable to catch assertion errors in case element was not found
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return null;
}
/**
* This is a generic method to enable the execution of the native mobile
* commands found herein: appium.io
*
* Note: This method does no validation on the output of the executed JavaScript
*
* @param command the desired mobile command to be executed. e.g., "mobile:
* scroll"
* @param parameters a map of the key, value parameters for this command. e.g.,
* ImmutableMap.of("direction", "down")
* @return a self-reference to be used to chain actions
*/
public FluentElementActions executeNativeMobileCommand(String command, Map parameters) {
try {
ElementActionsHelper.executeNativeMobileCommandUsingJavascript(DriverFactoryHelper.getDriver().get(), command, parameters);
var testData = "Command: " + command + ", Parameters: " + parameters;
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), null, Thread.currentThread().getStackTrace()[1].getMethodName(), testData, null, null);
} catch (Exception rootCauseException) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), null, rootCauseException);
}
return this;
}
/**
* Clicks on a certain element using Selenium WebDriver, or JavaScript
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @return a self-reference to be used to chain actions
*/
public FluentElementActions click(By elementLocator) {
if (DriverFactoryHelper.isMobileNativeExecution()) {
new TouchActions(DriverFactoryHelper.getDriver().get()).tap(elementLocator);
} else {
//rewriting click logic to optimize performance and fully support shadowDom elements
// get screenshot before doing anything to be attached in animated GIF (if any) or if screenshots are set to always
List screenshot = ElementActionsHelper.takeScreenshot(DriverFactoryHelper.getDriver().get(), elementLocator, "click", null, true);
ElementInformation elementInformation = new ElementInformation();
try {
// try performing move to element followed by click
elementInformation = ElementInformation.fromList(ElementActionsHelper.performActionAgainstUniqueElementIgnoringVisibility(DriverFactoryHelper.getDriver().get(), elementLocator, ElementAction.CLICK));
} catch (Throwable throwable) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
// get element name
var elementName = elementInformation.getElementName();
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, "", screenshot, elementName);
}
return this;
}
/**
* Clicks on certain element using javaScript only
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @return a self-reference to be used to chain actions
*/
public FluentElementActions clickUsingJavascript(By elementLocator) {
try {
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), elementLocator);
List screenshot = ElementActionsHelper.takeScreenshot(DriverFactoryHelper.getDriver().get(), elementLocator, "clickUsingJavascript", null, true);
ElementActionsHelper.clickUsingJavascript(DriverFactoryHelper.getDriver().get(), elementLocator);
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, "", screenshot, elementName);
} catch (Throwable throwable) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return this;
}
/**
* If the element is outside the viewport, scrolls the bottom of the element to the bottom of the viewport.
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @return a self-reference to be used to chain actions
*/
public FluentElementActions scrollToElement(By elementLocator) {
// if mobile, call swipeElementIntoView(null, targetElementLocator, swipeDirection); for convenience
if (DriverFactoryHelper.isMobileNativeExecution()) {
performTouchAction().swipeElementIntoView(elementLocator, TouchActions.SwipeDirection.DOWN);
}
try {
ElementActionsHelper.scrollToFindElement(DriverFactoryHelper.getDriver().get(), elementLocator);
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), null, null, ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), elementLocator));
} catch (Exception throwable) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return this;
}
/**
* Waits for the element to be clickable, and then clicks and holds it.
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @return a self-reference to be used to chain actions
*/
public FluentElementActions clickAndHold(By elementLocator) {
try {
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), elementLocator);
List screenshot = ElementActionsHelper.takeScreenshot(DriverFactoryHelper.getDriver().get(), elementLocator, "clickAndHold", null, true);
WebElement element = (WebElement) ElementActionsHelper.identifyUniqueElement(DriverFactoryHelper.getDriver().get(), elementLocator).get(1);
if (Boolean.FALSE.equals(ElementActionsHelper.waitForElementToBeClickable(DriverFactoryHelper.getDriver().get(), elementLocator, "clickAndHold"))) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), "element is not clickable", elementLocator);
}
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, "", screenshot, elementName);
} catch (Throwable throwable) {
// has to be throwable to catch assertion errors in case element was not found
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return this;
}
/**
* Attempts to perform a native clipboard action on the text from a certain web
* element, like copy/cut/paste
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @param action supports the following actions "copy", "paste", "cut",
* "select all", "unselect"
* @return a self-reference to be used to chain actions
*/
public FluentElementActions clipboardActions(By elementLocator, ClipboardAction action) {
try {
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), elementLocator);
boolean wasActionPerformed = ElementActionsHelper.performClipboardActions(DriverFactoryHelper.getDriver().get(), action);
if (Boolean.TRUE.equals(wasActionPerformed)) {
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), action.getValue(), null, elementName);
} else {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), action.getValue(), elementLocator);
}
} catch (Exception throwable) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return this;
}
/**
* Double-clicks on an element using Selenium WebDriver's Actions Library
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @return a self-reference to be used to chain actions
*/
public FluentElementActions doubleClick(By elementLocator) {
try {
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), elementLocator);
// takes screenshot before clicking the element out of view
var screenshot = ElementActionsHelper.takeScreenshot(DriverFactoryHelper.getDriver().get(), elementLocator, "doubleClick", null, true);
List> attachments = new LinkedList<>();
attachments.add(screenshot);
try {
(new Actions(DriverFactoryHelper.getDriver().get())).moveToElement(((WebElement) ElementActionsHelper.identifyUniqueElement(DriverFactoryHelper.getDriver().get(), elementLocator).get(1))).doubleClick().perform();
} catch (Exception e) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, e);
}
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), null, attachments, elementName);
} catch (Throwable throwable) {
// has to be throwable to catch assertion errors in case element was not found
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return this;
}
/**
* Drags the source element and drops it onto the destination element
*
* @param sourceElementLocator the locator of the source webElement that
* should be dragged under test (By xpath, id,
* selector, name ...etc)
* @param destinationElementLocator the locator of the target webElement that
* should receive the dropped source element
* under test (By xpath, id, selector, name
* ...etc)
* @return a self-reference to be used to chain actions
*/
public FluentElementActions dragAndDrop(By sourceElementLocator, By destinationElementLocator) {
try {
Exception exception = new Exception();
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), sourceElementLocator);
// replaced canFindUniqueElementForInternalUse, with countFoundElements for
// destinationElement to bypass the check for element visibility
// get source element start location
String startLocation = ((WebElement) ElementActionsHelper.identifyUniqueElement(DriverFactoryHelper.getDriver().get(), sourceElementLocator).get(1)).getLocation().toString();
// attempt to perform drag and drop
try {
ElementActionsHelper.dragAndDropUsingJavascript(DriverFactoryHelper.getDriver().get(), sourceElementLocator, destinationElementLocator);
} catch (Exception rootCauseException) {
exception = rootCauseException;
ReportManagerHelper.logDiscrete(rootCauseException);
}
// get source element end location
String endLocation = ((WebElement) ElementActionsHelper.identifyUniqueElement(DriverFactoryHelper.getDriver().get(), sourceElementLocator).get(1)).getLocation().toString();
String reportMessage = "Start point: " + startLocation + ", End point: " + endLocation;
if (!endLocation.equals(startLocation)) {
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), sourceElementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), reportMessage, null, elementName);
} else {
try {
ElementActionsHelper.dragAndDropUsingActions(DriverFactoryHelper.getDriver().get(), sourceElementLocator, destinationElementLocator);
} catch (Exception rootCauseException) {
if (!exception.equals(new Exception())) {
rootCauseException.addSuppressed(exception);
}
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), sourceElementLocator, rootCauseException);
}
// get source element end location
endLocation = ((WebElement) ElementActionsHelper.identifyUniqueElement(DriverFactoryHelper.getDriver().get(), sourceElementLocator).get(1)).getLocation().toString();
if (!endLocation.equals(startLocation)) {
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), sourceElementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), reportMessage, null, elementName);
} else {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), reportMessage, sourceElementLocator);
}
}
} catch (Throwable throwable) {
// has to be throwable to catch assertion errors in case element was not found
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), sourceElementLocator, throwable);
}
return this;
}
/**
* Drags the source element and drops it onto the determined offset
*
* @param sourceElementLocator the locator of the source webElement that should
* be dragged under test (By xpath, id, selector,
* name ...etc)
* @param xOffset the horizontal offset by which the element should
* be moved
* @param yOffset the vertical offset by which the element should
* be moved
* @return a self-reference to be used to chain actions
*/
public FluentElementActions dragAndDropByOffset(By sourceElementLocator, int xOffset, int yOffset) {
try {
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), sourceElementLocator);
WebElement sourceElement = ((WebElement) ElementActionsHelper.identifyUniqueElement(DriverFactoryHelper.getDriver().get(), sourceElementLocator).get(1));
String startLocation = sourceElement.getLocation().toString();
// attempt to perform drag and drop
try {
(new Actions(DriverFactoryHelper.getDriver().get())).dragAndDropBy(((WebElement) ElementActionsHelper.identifyUniqueElement(DriverFactoryHelper.getDriver().get(), sourceElementLocator).get(1)), xOffset, yOffset).build()
.perform();
} catch (Exception rootCauseException) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), sourceElementLocator, rootCauseException);
}
String endLocation = ((WebElement) ElementActionsHelper.identifyUniqueElement(DriverFactoryHelper.getDriver().get(), sourceElementLocator).get(1)).getLocation().toString();
if (!endLocation.equals(startLocation)) {
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), sourceElementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), "Start point: " + startLocation + ", End point: " + endLocation, null, elementName);
} else {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), "Start point = End point: " + endLocation, sourceElementLocator);
}
} catch (Exception throwable) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), sourceElementLocator, throwable);
}
return this;
}
/**
* Get the value of the given attribute of the element. Will return the current
* value, even if this has been modified after the page has been loaded.
*
* More exactly, this method will return the value of the property with the
* given name, if it exists. If it does not, then the value of the attribute
* with the given name is returned. If neither exists, null is returned.
*
* The "style" attribute is converted as best can be to a text representation
* with a trailing semicolon.
*
* The following are deemed to be "boolean" attributes, and will return either
* "true" or null:
*
* async, autofocus, autoplay, checked, compact, complete, controls, declare,
* defaultchecked, defaultselected, defer, disabled, draggable, ended,
* formnovalidate, hidden, indeterminate, iscontenteditable, ismap, itemscope,
* loop, multiple, muted, nohref, noresize, noshade, novalidate, nowrap, open,
* paused, pubdate, readonly, required, reversed, scoped, seamless, seeking,
* selected, truespeed, willvalidate
*
* Finally, the following commonly mis-capitalized attribute/property names are
* evaluated as expected:
*
* If the given name is "class", the "className" property is returned. If the
* given name is "readonly", the "readOnly" property is returned. Note: The
* reason for this behavior is that users frequently confuse attributes and
* properties. If you need to do something more precise, e.g., refer to an
* attribute even when a property of the same name exists, then you should
* evaluate Javascript to obtain the result you desire.
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @param attributeName the target attribute of the webElement under test
* @return the value of the target attribute of the webElement under test
*/
@SuppressWarnings("SpellCheckingInspection")
public String getAttribute(By elementLocator, String attributeName) {
ReportManager.logDiscrete("Attempting to getAttribute \"" + attributeName + "\" from elementLocator \"" + elementLocator + "\".");
try {
var elementInformation = ElementInformation.fromList(ElementActionsHelper.performActionAgainstUniqueElementIgnoringVisibility(DriverFactoryHelper.getDriver().get(), elementLocator, ElementAction.GET_ATTRIBUTE, attributeName));
try {
String elementAttribute = elementInformation.getActionResult();
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), elementAttribute, null, elementInformation.getElementName());
return elementAttribute;
} catch (UnsupportedCommandException rootCauseException) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, rootCauseException);
return null;
}
} catch (Throwable throwable) {
// has to be throwable to catch assertion errors in case element was not found
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return null;
}
/**
* Get the value of a given CSS property. Color values should be returned as
* RGBA strings, so, for example if the "background-color" property is SetProperty as
* "green" in the HTML source, the returned value will be "RGBA(0, 255, 0, 1)".
* Note that shorthand CSS properties (e.g. background, font, border,
* border-top, margin, margin-top, padding, padding-top, list-style, outline,
* pause, cue) are not returned, in accordance with the DOM CSS2 specification -
* you should directly access the longhand properties (e.g. background-color) to
* access the desired values.
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @param propertyName the target CSS property of the webElement under test
* @return the value of the target CSS property of the webElement under test
*/
public String getCSSProperty(By elementLocator, String propertyName) {
try {
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), elementLocator);
String elementCssProperty = ((WebElement) ElementActionsHelper.identifyUniqueElement(DriverFactoryHelper.getDriver().get(), elementLocator).get(1)).getCssValue(propertyName);
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), elementCssProperty, null, elementName);
return elementCssProperty;
} catch (Throwable throwable) {
// has to be throwable to catch assertion errors in case element was not found
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return null;
}
/**
* Returns the handle for currently active context. This can be used to switch
* to this context at a later time.
*
* @return The current context handle
*/
public String getContext() {
String context = "";
if (DriverFactoryHelper.getDriver().get() instanceof AndroidDriver androidDriver) {
context = androidDriver.getContext();
} else if (DriverFactoryHelper.getDriver().get() instanceof IOSDriver iosDriver) {
context = iosDriver.getContext();
} else {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), null);
}
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), null, Thread.currentThread().getStackTrace()[1].getMethodName(), context, null, null);
return context;
}
/**
* Switches focus to another context
*
* @param context The name of the context or the handle as returned by
* ElementActions.getContext(WebDriver driver)
* @return a self-reference to be used to chain actions
*/
public FluentElementActions setContext(String context) {
if (DriverFactoryHelper.getDriver().get() instanceof AndroidDriver androidDriver) {
androidDriver.context(context);
} else if (DriverFactoryHelper.getDriver().get() instanceof IOSDriver iosDriver) {
iosDriver.context(context);
} else {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), context, null);
}
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), null, Thread.currentThread().getStackTrace()[1].getMethodName(), context, null, null);
return this;
}
/**
* Returns a list of unique handles for all the currently open contexts. This
* can be used to switch to any of these contexts at a later time.
*
* @return list of context handles
*/
public List getContextHandles() {
List windowHandles = new ArrayList<>();
if (DriverFactoryHelper.getDriver().get() instanceof AndroidDriver androidDriver) {
windowHandles.addAll(androidDriver.getContextHandles());
} else if (DriverFactoryHelper.getDriver().get() instanceof IOSDriver iosDriver) {
windowHandles.addAll(iosDriver.getContextHandles());
} else {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), null);
}
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), null, Thread.currentThread().getStackTrace()[1].getMethodName(), String.valueOf(windowHandles), null, null);
return windowHandles;
}
/**
* Retrieves text from the target element and returns it as a string value.
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @return the text value of the target webElement
*/
public String getText(By elementLocator) {
try {
var elementInformation = ElementInformation.fromList(ElementActionsHelper.identifyUniqueElementIgnoringVisibility(DriverFactoryHelper.getDriver().get(), elementLocator));
var elementName = elementInformation.getElementName();
String elementText;
try {
elementText = (elementInformation.getFirstElement()).getText();
} catch (WebDriverException webDriverException) {
elementText = ElementInformation.fromList(ElementActionsHelper.performActionAgainstUniqueElementIgnoringVisibility(DriverFactoryHelper.getDriver().get(), elementInformation.getLocator(), ElementAction.GET_TEXT)).getActionResult();
}
if ((elementText == null || elementText.trim().equals("")) && !DriverFactoryHelper.isMobileNativeExecution()) {
try {
elementText = (elementInformation.getFirstElement()).getAttribute(ElementActionsHelper.TextDetectionStrategy.CONTENT.getValue());
} catch (WebDriverException webDriverException) {
elementText = ElementInformation.fromList(ElementActionsHelper.performActionAgainstUniqueElementIgnoringVisibility(DriverFactoryHelper.getDriver().get(), elementInformation.getLocator(), ElementAction.GET_CONTENT)).getActionResult();
}
}
if ((elementText == null || elementText.trim().equals("")) && !DriverFactoryHelper.isMobileNativeExecution()) {
try {
elementText = (elementInformation.getFirstElement()).getAttribute(ElementActionsHelper.TextDetectionStrategy.VALUE.getValue());
} catch (WebDriverException webDriverException) {
elementText = ElementInformation.fromList(ElementActionsHelper.performActionAgainstUniqueElementIgnoringVisibility(DriverFactoryHelper.getDriver().get(), elementInformation.getLocator(), ElementAction.GET_VALUE)).getActionResult();
}
}
if (elementText == null) {
elementText = "";
}
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), elementText, null, elementName);
return elementText;
} catch (Throwable throwable) {
// has to be throwable to catch assertion errors in case element was not found
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return null;
}
/**
* Returns the unique handle for currently active window. This can be used to
* switch to this window at a later time.
*
* @return window handle
*/
public String getWindowHandle() {
String nameOrHandle = DriverFactoryHelper.getDriver().get().getWindowHandle();
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), null, Thread.currentThread().getStackTrace()[1].getMethodName(), nameOrHandle, null, null);
return nameOrHandle;
}
/**
* Returns a list of unique handles for all the currently open windows. This can
* be used to switch to any of these windows at a later time.
*
* @return list of window handles
*/
public List getWindowHandles() {
List windowHandles = new ArrayList<>(DriverFactoryHelper.getDriver().get().getWindowHandles());
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), null, Thread.currentThread().getStackTrace()[1].getMethodName(), String.valueOf(windowHandles), null, null);
return windowHandles;
}
/**
* Hovers over target element. If you want to hover on a webElement to expose
* another webElement and click on it, use hoverAndClick instead for a more
* reliable result.
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @return a self-reference to be used to chain actions
*/
public FluentElementActions hover(By elementLocator) {
try {
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), elementLocator);
try {
(new Actions(DriverFactoryHelper.getDriver().get())).moveToElement(((WebElement) ElementActionsHelper.identifyUniqueElement(DriverFactoryHelper.getDriver().get(), elementLocator).get(1))).perform();
} catch (Exception rootCauseException) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, rootCauseException);
}
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), null, null, elementName);
} catch (Throwable throwable) {
// has to be throwable to catch assertion errors in case element was not found
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return this;
}
/**
* Hovers over the hoverElements in sequence then clicks the clickableElement
*
* @param hoverElementLocators the list of locators of the webElements under
* test upon which the hover action will be
* performed in sequence (By xpath, id, selector,
* name ...etc)
* @param clickableElementLocator the locator of the webElement under test upon
* which the click action will be performed (By
* xpath, id, selector, name ...etc)
* @return a self-reference to be used to chain actions
*/
public FluentElementActions hoverAndClick(List hoverElementLocators, By clickableElementLocator) {
hoverElementLocators.forEach(this::hover);
click(clickableElementLocator);
return this;
}
/**
* Sends a key-press to the target element.
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @param key the key that should be pressed
* @return a self-reference to be used to chain actions
*/
public FluentElementActions keyPress(By elementLocator, Keys key) {
try {
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), elementLocator);
List screenshot = ElementActionsHelper.takeScreenshot(DriverFactoryHelper.getDriver().get(), elementLocator, "keyPress", null, true);
// takes screenshot before moving the element out of view
((WebElement) ElementActionsHelper.identifyUniqueElement(DriverFactoryHelper.getDriver().get(), elementLocator).get(1)).sendKeys(key);
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, key.name(), screenshot, elementName);
} catch (Throwable throwable) {
// has to be throwable to catch assertion errors in case element was not found
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), key.name(), elementLocator, throwable);
}
return this;
}
/**
* Selects an element from a dropdown list using its displayed text or attribute Value
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @param valueOrVisibleText the text of the choice that you need to select from the
* target dropDown menu or the string value of attribute"value"
* @return a self-reference to be used to chain actions
*/
public FluentElementActions select(By elementLocator, String valueOrVisibleText) {
try {
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), elementLocator);
//add forced check that the select element actually has options and is not empty
if (!Boolean.TRUE.equals(ElementActionsHelper.waitForElementTextToBeNot(DriverFactoryHelper.getDriver().get(), elementLocator, ""))) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), valueOrVisibleText , elementLocator);
}
boolean isOptionFound = false;
var availableOptionsList = (new Select(((WebElement) ElementActionsHelper.identifyUniqueElement(DriverFactoryHelper.getDriver().get(), elementLocator).get(1)))).getOptions();
for (int i = 0; i < availableOptionsList.size(); i++) {
String visibleText = availableOptionsList.get(i).getText();
String value = availableOptionsList.get(i).getAttribute("value");
if (visibleText.trim().equals(valueOrVisibleText) || value.trim().equals(valueOrVisibleText)) {
(new Select(((WebElement) ElementActionsHelper.identifyUniqueElement(DriverFactoryHelper.getDriver().get(), elementLocator).get(1)))).selectByIndex(i);
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), valueOrVisibleText, null, elementName);
isOptionFound = true;
break;
}
}
if (Boolean.FALSE.equals(isOptionFound)) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), valueOrVisibleText, elementLocator);
}
} catch (Throwable throwable) {
// has to be throwable to catch assertion errors in case element was not found
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), valueOrVisibleText, elementLocator, throwable);
}
return this;
}
/**
* Used to SetProperty value for an element (hidden or visible) using javascript
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @param value the desired value that should be SetProperty for the target
* element
* @return a self-reference to be used to chain actions
*/
public FluentElementActions setValueUsingJavaScript(By elementLocator, String value) {
try {
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), elementLocator);
Boolean valueSetSuccessfully = ElementActionsHelper.setValueUsingJavascript(elementLocator, value);
if (Boolean.TRUE.equals(valueSetSuccessfully)) {
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), value, null, elementName);
} else {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator);
}
} catch (Exception throwable) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return this;
}
/**
* Used to submit a form using javascript
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @return a self-reference to be used to chain actions
*/
public FluentElementActions submitFormUsingJavaScript(By elementLocator) {
try {
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), elementLocator);
try {
ElementActionsHelper.submitFormUsingJavascript(DriverFactoryHelper.getDriver().get(), elementLocator);
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), null, null, elementName);
} catch (Exception rootCauseException) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, rootCauseException);
}
} catch (Exception throwable) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return this;
}
/**
* Switches focus to a certain iFrame, is mainly used in coordination with
* {@link #switchToDefaultContent()} to navigate inside any iFrame
* layer and go back to the main page
*
* @param elementLocator the locator of the iFrame webElement under test (By
* xpath, id, selector, name ...etc)
* @return a self-reference to be used to chain actions
*/
public FluentElementActions switchToIframe(By elementLocator) {
try {
// DriverFactoryHelper.getDriver().get().switchTo().frame(
var elementInformation = ElementInformation.fromList(
ElementActionsHelper.identifyUniqueElement(DriverFactoryHelper.getDriver().get(), elementLocator));
// .getFirstElement());
LocatorBuilder.setIFrameLocator(elementInformation.getLocator());
// note to self: remove elementLocator in case of bug in screenshot manager
boolean discreetLoggingState = ReportManagerHelper.getDiscreteLogging();
ReportManagerHelper.setDiscreteLogging(true);
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), String.valueOf(elementLocator), null, elementInformation.getElementName());
ReportManagerHelper.setDiscreteLogging(discreetLoggingState);
} catch (Throwable throwable) {
// has to be throwable to catch assertion errors in case element was not found
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return this;
}
/**
* Switches focus to default content, is mainly used in coordination with
* {@link #switchToIframe(By)} to exit any iFrame layer and go back
* to the main page
*
* @return a self-reference to be used to chain actions
*/
@SuppressWarnings("UnusedReturnValue")
public FluentElementActions switchToDefaultContent() {
try {
DriverFactoryHelper.getDriver().get().switchTo().defaultContent();
LocatorBuilder.setIFrameLocator(null);
boolean discreetLoggingState = ReportManagerHelper.getDiscreteLogging();
ReportManagerHelper.setDiscreteLogging(true);
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), null, Thread.currentThread().getStackTrace()[1].getMethodName(), null, null, null);
ReportManagerHelper.setDiscreteLogging(discreetLoggingState);
} catch (Exception rootCauseException) {
// failAction(DriverFactoryHelper.getDriver().get(), null, rootCauseException);
}
// if there is no last used driver or no drivers in the drivers list, do
// nothing...
// return new FluentElementActions(Objects.requireNonNull(DriverFactoryHelper.getDriver()).get());
return this;
}
/**
* gets the current frame
*
* @return currentFrame the current frame name
*/
public String getCurrentFrame() {
String currentFrame = "";
try {
if (LocatorBuilder.getIFrameLocator() != null) {
currentFrame = (String) ((JavascriptExecutor) DriverFactoryHelper.getDriver().get().switchTo().frame(DriverFactoryHelper.getDriver().get().findElement(LocatorBuilder.getIFrameLocator())))
.executeScript("return self.name");
} else {
currentFrame = (String) ((JavascriptExecutor) DriverFactoryHelper.getDriver().get()).executeScript("return self.name");
}
ReportManager.logDiscrete("Current frame name: \"" + currentFrame + "\"");
} catch (Exception rootCauseException) {
ReportManager.logDiscrete(String.valueOf(rootCauseException));
}
return currentFrame;
}
/**
* Checks if there is any text in an element, clears it, then types the required
* string into the target element.
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @param text the target text that needs to be typed into the target
* webElement
* @return a self-reference to be used to chain actions
*/
public FluentElementActions type(By elementLocator, String text) {
try {
var elementInformation = ElementInformation.fromList(ElementActionsHelper.identifyUniqueElementIgnoringVisibility(DriverFactoryHelper.getDriver().get(), elementLocator));
String actualResult = ElementActionsHelper.typeWrapper(elementInformation, text);
var elementName = elementInformation.getElementName();
if (actualResult.equals(text)) {
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), text, null, elementName);
} else {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), "Expected to type: \"" + text + "\", but ended up with: \"" + actualResult + "\"",
elementLocator);
}
} catch (Throwable throwable) {
// has to be throwable to catch assertion errors in case element was not found
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return this;
}
/**
* Appends the required string into the target element, regardless of the
* current text value.
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @param text the target text that needs to be appended into the
* target webElement
* @return a self-reference to be used to chain actions
*/
public FluentElementActions typeAppend(By elementLocator, String text) {
try {
if (text != null) {
var elementInformation = ElementInformation.fromList(ElementActionsHelper.performActionAgainstUniqueElement(DriverFactoryHelper.getDriver().get(), elementLocator, ElementAction.SEND_KEYS, text));
var elementName = elementInformation.getElementName();
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), text, null, elementName);
}
} catch (Throwable throwable) {
// has to be throwable to catch assertion errors in case element was not found
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return this;
}
/**
* ValidationEnums the required file path into an input[type='file'] button, to
* successfully upload the target file.
*
* @param elementLocator the locator of the webElement under test (By xpath,
* id, selector, name ...etc)
* @param filePath the full path to the file that needs to be uploaded, it can be absolute or relative
* path, Engine will detect that
* @return a self-reference to be used to chain actions
*/
public FluentElementActions typeFileLocationForUpload(By elementLocator, String filePath) {
var absoluteFilePath = filePath;
if (filePath.startsWith("src")) {
absoluteFilePath = FileActions.getInstance().getAbsolutePath(filePath);
}
String internalAbsoluteFilePath = absoluteFilePath.replace("/", FileSystems.getDefault().getSeparator());
try {
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), elementLocator);
List screenshot = ElementActionsHelper.takeScreenshot(DriverFactoryHelper.getDriver().get(), elementLocator, "typeFileLocationForUpload", null, true);
// takes screenshot before clicking the element out of view
try {
((WebElement) ElementActionsHelper.identifyUniqueElementIgnoringVisibility(DriverFactoryHelper.getDriver().get(), elementLocator).get(1)).sendKeys(internalAbsoluteFilePath);
} catch (InvalidArgumentException e) {
//this happens when the file path doesn't exist
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), internalAbsoluteFilePath, elementLocator, e);
} catch (ElementNotInteractableException | NoSuchElementException exception1) {
ElementActionsHelper.changeWebElementVisibilityUsingJavascript(DriverFactoryHelper.getDriver().get(), elementLocator, true);
try {
((WebElement) ElementActionsHelper.identifyUniqueElement(DriverFactoryHelper.getDriver().get(), elementLocator).get(1)).sendKeys(internalAbsoluteFilePath);
} catch (WebDriverException rootCauseException) {
rootCauseException.addSuppressed(exception1);
// happened for the first time on MacOSX due to incorrect file path separator
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), internalAbsoluteFilePath, elementLocator, rootCauseException);
}
try {
ElementActionsHelper.changeWebElementVisibilityUsingJavascript(DriverFactoryHelper.getDriver().get(), elementLocator, false);
} catch (NoSuchElementException | StaleElementReferenceException e) {
// this exception is sometimes thrown on firefox after the upload has been
// successful, since we don't have to return the style to what it was, then it's
// okay to do nothing here.
ReportManagerHelper.logDiscrete(e);
}
}
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, internalAbsoluteFilePath, screenshot, elementName);
} catch (Throwable throwable) {
// has to be throwable to catch assertion errors in case element was not found
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return this;
}
/**
* Checks if there is any text in an element, clears it, then types the required
* string into the target element. Obfuscates the written text in the output
* report. This action should be used for writing passwords and secure text.
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @param text the target text that needs to be typed into the target
* webElement
* @return a self-reference to be used to chain actions
*/
public FluentElementActions typeSecure(By elementLocator, String text) {
try {
var elementInformation = ElementInformation.fromList(ElementActionsHelper.identifyUniqueElementIgnoringVisibility(DriverFactoryHelper.getDriver().get(), elementLocator));
String actualResult = ElementActionsHelper.typeWrapper(elementInformation, text);
var elementName = (String) elementInformation.getElementName();
if (actualResult.equals(text)) {
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), ElementActionsHelper.OBFUSCATED_STRING.repeat(text.length()), null, elementName);
} else {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), "Expected to type: \"" + text + "\", but ended up with: \""
+ actualResult + "\"", elementLocator);
}
} catch (Throwable throwable) {
// has to be throwable to catch assertion errors in case element was not found
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return this;
}
/**
* Waits dynamically for a specific element to be present in DOM, and ready to interact with, on the current page.
*
* @param elementLocator the locator of the webElement under test (By xpath,
* id, selector, name ...etc)
* @return a self-reference to be used to chain actions
*/
public FluentElementActions waitToBeReady(By elementLocator) {
return waitToBeReady(elementLocator, true);
}
public FluentElementActions waitToBeReady(By elementLocator, boolean isExpectedToBeVisible) {
ReportManager.logDiscrete("Waiting for element to be present; elementLocator \"" + elementLocator + "\", isExpectedToBeVisible\"" + isExpectedToBeVisible + "\"...");
String reportMessage = "Waited for the element's state of visibility to be (" + isExpectedToBeVisible
+ "). Element locator (" + ElementActionsHelper.formatLocatorToString(elementLocator) + ")";
try {
var elementInformation = ElementInformation.fromList(ElementActionsHelper.performActionAgainstUniqueElementIgnoringVisibility(DriverFactoryHelper.getDriver().get(), elementLocator, ElementAction.IS_DISPLAYED));
boolean isDisplayed = Boolean.parseBoolean(elementInformation.getActionResult());
//element is present
if (isExpectedToBeVisible == isDisplayed) {
//either expected to be visible and is displayed, or not expected to be visible and not displayed
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), reportMessage, null, elementInformation.getElementName());
} else //noinspection ConstantValue
if (!isExpectedToBeVisible && isDisplayed) {
// Element is displayed and needed to wait until it's invisible
if (ElementActionsHelper.waitForElementInvisibility(elementLocator)) {
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), reportMessage, null, elementInformation.getElementName());
} else {
// Element still exists after timeout
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), reportMessage, elementLocator);
}
} else {
// Element is not displayed
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), reportMessage, elementLocator);
}
} catch (Throwable throwable) {
// has to be throwable to catch assertion errors in case element was not found
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), reportMessage, null, throwable);
}
return this;
}
/**
* Waits dynamically for a specific element to be detached from DOM, or hidden, on the current page.
*
* @param elementLocator the locator of the webElement under test (By xpath,
* id, selector, name ...etc)
* @return a self-reference to be used to chain actions
*/
public FluentElementActions waitToBeInvisible(By elementLocator) {
return waitToBeReady(elementLocator, false);
}
/**
* Waits dynamically for a specific element's text to change from the initial
* value to a new unknown value. Waits until the default element identification timeout
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @param initialValue the initial text value of the target webElement
* @return a self-reference to be used to chain actions
*/
@SuppressWarnings("UnusedReturnValue")
public FluentElementActions waitForTextToChange(By elementLocator, String initialValue) {
try {
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), elementLocator);
if (!Boolean.TRUE.equals(ElementActionsHelper.waitForElementTextToBeNot(DriverFactoryHelper.getDriver().get(), elementLocator, initialValue))) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), initialValue, elementLocator);
}
try {
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(),
"from: \"" + initialValue + "\", to: \"" + getText(elementLocator) + "\"", null, elementName);
} catch (Exception e) {
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(),
"from: \"" + initialValue + "\", to a new value.", null, elementName);
}
} catch (Exception throwable) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return this;
}
/**
* Waits dynamically for a specific element's attribute to be a certain value.
* Waits until the default element identification timeout
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @param att the attribute name of the target webElement
* @param expectedAttValue the expected value of the attribute
* @return a self-reference to be used to chain actions
*/
public FluentElementActions waitToAttribute(By elementLocator, String att, String expectedAttValue) {
try {
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), elementLocator);
if (Boolean.FALSE.equals(ElementActionsHelper
.waitForElementAttributeToBe(DriverFactoryHelper.getDriver().get(), elementLocator,
att, expectedAttValue))) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator);
}
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(),
"wait for element attribute \"" + att + "\" to be \"" + expectedAttValue + "\"", null, elementName);
} catch (Exception throwable) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return this;
}
/**
* Checks to see if an element is displayed
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @return boolean value, true if the element is displayed, and false if the
* element is not displayed
*/
public boolean isElementDisplayed(By elementLocator) {
try {
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), elementLocator);
boolean isDisplayed = ((WebElement) ElementActionsHelper.identifyUniqueElement(DriverFactoryHelper.getDriver().get(), elementLocator).get(1)).isDisplayed();
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), null, null, elementName);
return isDisplayed;
} catch (Throwable throwable) {
// has to be throwable to catch assertion errors in case element was not found
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
}
return false;
}
/**
* Checks to see if an element is clickable
*
* @param elementLocator the locator of the webElement under test (By xpath, id,
* selector, name ...etc)
* @return boolean value, true if the element is clickable, and false if the
* element is not clickable
*/
public boolean isElementClickable(By elementLocator) {
try {
var elementName = ElementActionsHelper.getElementName(DriverFactoryHelper.getDriver().get(), elementLocator);
if (ElementActionsHelper.waitForElementToBeClickable(DriverFactoryHelper.getDriver().get(), elementLocator, "")) {
//element is clickable
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), "element is clickable", null, elementName);
return true;
} else {
//element is not clickable
ElementActionsHelper.passAction(DriverFactoryHelper.getDriver().get(), elementLocator, Thread.currentThread().getStackTrace()[1].getMethodName(), "element is not clickable", null, elementName);
return false;
}
} catch (Exception throwable) {
ElementActionsHelper.failAction(DriverFactoryHelper.getDriver().get(), elementLocator, throwable);
//unreachable code
return false;
}
}
public FluentElementActions captureScreenshot(By elementLocator) {
ReportManagerHelper.log("Capture element screenshot", Collections.singletonList(ScreenshotManager.prepareImageForReport(ScreenshotManager.takeElementScreenshot(DriverFactoryHelper.getDriver().get(), elementLocator), "captureScreenshot")));
return this;
}
}