com.codacy.scoobydoo.web.WebFragment Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scooby-doo-fwk Show documentation
Show all versions of scooby-doo-fwk Show documentation
Automated testing framework
package com.codacy.scoobydoo.web;
import com.codacy.scoobydoo.LoggingHelper;
import com.codacy.scoobydoo.configuration.Configuration;
import com.codacy.scoobydoo.utils.Utils;
import com.codacy.scoobydoo.utils.WebUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Action;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
public abstract class WebFragment {
public Configuration config;
public RemoteWebDriver driver;
public ScreenShotHelper screenShotHelper;
public WebUtils webUtils;
public WebFragment(RemoteWebDriver driver, Configuration configuration) {
Objects.requireNonNull(driver, "Driver cannot be null. Please ensure that the 'type' value is 'end' or 'web' on the test suite file you are running.");
this.driver = driver;
config = configuration;
screenShotHelper = new ScreenShotHelper(driver, configuration);
webUtils = new WebUtils(driver, configuration);
}
public void assertElementDoesNotExist(By elementLocator) {
boolean elementExists;
try {
driver.findElement(elementLocator);
elementExists = true;
} catch(NoSuchElementException ignored) {
elementExists = false;
}
assertThat("Element with locator [" + elementLocator + "] exists but it shouldn't.", elementExists, is(false));
}
// use getElement(elementLocator) (.assertIsDisplayed()) .assertHasExactText(expectedText) instead.
@Deprecated
public void assertElementHasVisibleText(By elementLocator, String expectedText) {
assertElementHasVisibleText(driver.findElement(elementLocator), expectedText);
}
// use getElement(elementLocator) (.assertIsDisplayed()) .assertHasExactText(expectedText) instead.
@Deprecated
public void assertElementHasVisibleText(WebElement targetElement, String expectedText) {
assertTrue(targetElement.isDisplayed());
assertEquals(targetElement.getText(), expectedText);
}
// Use this when the equivalent assertElementHasVisibleText method doesn't work.
public void assertElementHasVisibleTextValue(By elementLocator, String expectedText) {
assertElementHasVisibleTextValue(driver.findElement(elementLocator), expectedText);
}
// Use this when the equivalent assertElementHasVisibleText method doesn't work.
public void assertElementHasVisibleTextValue(WebElement targetElement, String expectedText) {
assertTrue(targetElement.isDisplayed());
assertEquals(targetElement.getAttribute("value"), expectedText);
}
// Use getElement(elementLocator) (.assertIsDisplayed()) .assertTextMatchesRegEx(expectedTextRegEx) instead.
@Deprecated
public void assertElementHasVisibleTextWithRegEx(By elementLocator, String expectedTextRegEx) {
assertElementHasVisibleTextWithRegEx(driver.findElement(elementLocator), expectedTextRegEx);
}
// Use getElement(elementLocator) (.assertIsDisplayed()) .assertTextMatchesRegEx(expectedTextRegEx) instead.
@Deprecated
public void assertElementHasVisibleTextWithRegEx(WebElement targetElement, String expectedTextRegEx) {
assertTrue(targetElement.isDisplayed());
final String targetElementText = targetElement.getText();
assertTrue(targetElementText.matches(expectedTextRegEx),
"Target element text [" + targetElementText + "] does not matches expected RegEx [" + expectedTextRegEx + "].");
}
// use getElement(locator).assertIsDisplayed() instead.
@Deprecated
public void assertElementIsDisplayed(By locator) {
assertTrue(isElementDisplayed(locator), "Element with locator [" + locator + "] should be displayed but it isn't.");
}
// use assertElementDoesNotExist(locator) or getElement(locator).assertIsNotDisplayed() instead.
@Deprecated
public void assertElementIsNotDisplayed(By locator) {
assertFalse(isElementDisplayed(locator), "Element with locator [" + locator + "] should not be displayed but it is.");
}
public boolean doesElementExists(By locator) {
return driver.findElements(locator).size() > 0;
}
// Use this only when default method element.clear() doesn't work.
@Deprecated
public void forceClear(WebElementWrapper element) {
element.sendKeys(Keys.chord(Keys.CONTROL, "a", Keys.DELETE));
}
public WebDriver getDriver() {
return driver;
}
public WebElementWrapper getElement(By locator) {
return new WebElementWrapper(driver, config, locator);
}
public WebElementWrapper getElement(By locator, Duration timeout, Duration polling) {
return new WebElementWrapper(driver, config, locator, timeout, polling);
}
// use getElement(by).click() instead.
@Deprecated
public WebElementWrapper getElementWhenClickable(By by) {
return this.getElementWhenClickable(by, config.getTimeout().FIND_ELEMENT_WAIT_TIMEOUT, config.getTimeout().DEFAULT_POLLING);
}
// use getElement(by).click() instead.
@Deprecated
public WebElementWrapper getElementWhenClickable(By by, Duration timeout, Duration polling) {
String infoMessage = Utils.getWaitLogMessage(by, Utils.ElementProperty.CLICKABLE, timeout, polling);
String errorMessage = Utils.getWaitErrorLogMessage(by, Utils.ElementProperty.CLICKABLE, timeout);
waitForElementWithCondition(timeout, polling, ExpectedConditions.elementToBeClickable(by), infoMessage, errorMessage);
return new WebElementWrapper(driver, config, by);
}
// this should be private.
@Deprecated
public WebElementWrapper getElementWhenVisible(By locator) {
getElementWhenVisibleWithConfigurableTimeout(locator, config.getTimeout().FIND_ELEMENT_WAIT_TIMEOUT, config.getTimeout().DEFAULT_POLLING);
return new WebElementWrapper(driver, config, locator);
}
// this should be private.
@Deprecated
public WebElementWrapper getElementWhenVisibleWithConfigurableTimeout(By locator, Duration timeout, Duration polling) {
String infoMessage = Utils.getWaitLogMessage(locator, Utils.ElementProperty.VISIBLE, timeout, polling);
String errorMessage = Utils.getWaitErrorLogMessage(locator, Utils.ElementProperty.VISIBLE, timeout);
waitForElementWithCondition(timeout, polling, ExpectedConditions.visibilityOfElementLocated(locator), infoMessage, errorMessage);
return new WebElementWrapper(driver, config, locator);
}
public List getElements(By locator) {
List elements = driver.findElements(locator);
if(elements.isEmpty()) {
waitForElementToBeVisible(locator);
elements = driver.findElements(locator);
}
return elements;
}
public List getElementsByType(String elementType) {
return this.driver.findElements(By.tagName(elementType));
}
public List getVisibleElementsByType(String elementType) {
return getElementsByType(elementType)
.stream()
.filter(WebElement::isDisplayed)
.toList();
}
public void hoverMouseOverElement(By locator) {
WebElement targetElement = getElementWhenVisible(locator).getWebElement();
Action action = new Actions(getDriver())
.moveToElement(targetElement)
.build();
action.perform(); // for some reason, this had to be broken in 2 steps, otherwise no action would be performed.
}
public boolean isCheckboxChecked(By checkboxLocator) {
return getElement(checkboxLocator).getAttribute("checked") != null;
}
public boolean isElementDisplayed(By locator) {
try {
return driver.findElement(locator).isDisplayed();
} catch(NoSuchElementException ignored) {
return false;
}
}
public boolean retryStaleElement(By by, Consumer consumer) throws InterruptedException {
int attempts = 0;
while (attempts < 20) {
try {
Thread.sleep(500);
WebElement a = getDriver().findElement(by);
consumer.accept(a);
return true;
} catch (NoSuchElementException | TimeoutException | StaleElementReferenceException ignored) {
//Swallow
}
attempts++;
}
return false;
}
public boolean retryStaleElementClick(By by) {
try {
return retryStaleElement(by, WebElement::click);
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}
}
public boolean retryStaleElementDisplay(By by) {
try {
return retryStaleElement(by, WebElement::isDisplayed);
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}
}
public void scrollDown() {
JavascriptExecutor js = (JavascriptExecutor) getDriver();
js.executeScript("window.scrollBy(0,1000)");
}
public WebElementWrapper waitForElementToBeVisible(By locator) {
return waitForElementToBeVisible(locator, config.getTimeout().FIND_ELEMENT_WAIT_TIMEOUT);
}
public WebElementWrapper waitForElementToBeVisible(By locator, Duration timeout) {
webUtils.waitForCondition(timeout, ExpectedConditions.visibilityOfElementLocated(locator));
return getElement(locator);
}
public void waitForElementWithCondition(Duration timeout, Duration polling, ExpectedCondition expectedCondition, String infoMessage, String errorMessage) {
try {
screenShotHelper.takesScreenshotOnAction(infoMessage);
new FluentWait<>(driver)
.withTimeout(timeout)
.pollingEvery(polling)
.ignoreAll(Arrays.asList(StaleElementReferenceException.class, NoSuchElementException.class))
.until(expectedCondition);
} catch (Exception e) {
screenShotHelper.takesScreenshotOnError(errorMessage, e);
throw e;
}
}
// use waitForPageToLoad() instead.
@Deprecated
public void waitPageToLoad() {
waitForPageToLoad();
}
// use waitForPageToLoad(timeout) instead.
@Deprecated
public void waitPageToLoad(Duration timeout) {
waitForPageToLoad(timeout);
}
public void waitForPageToLoad() {
waitForPageToLoad(config.getTimeout().PAGE_LOAD_TIMEOUT, config.getTimeout().LONG_POLLING);
}
public void waitForPageToLoad(Duration timeout) {
waitForPageToLoad(timeout, config.getTimeout().LONG_POLLING);
}
public void waitForPageToLoad(Duration timeout, Duration polling) {
webUtils.waitForFunction(
webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"),
timeout, polling);
LoggingHelper.info("Page is loaded.");
}
public void waitForTextToBe(By locator, String targetText) {
waitForTextToBe(locator, targetText, config.getTimeout().FIND_ELEMENT_WAIT_TIMEOUT);
}
// Unfortunately this can't be moved to WebElementWrapper since Selenium does not provide a condition using element instead of locator.
public void waitForTextToBe(By locator, String targetText, Duration timeout) {
webUtils.waitForCondition(timeout, ExpectedConditions.textToBe(locator, targetText));
}
public void waitForTextToContain(By locator, String targetSubstring) {
waitForTextToContain(locator, targetSubstring, config.getTimeout().FIND_ELEMENT_WAIT_TIMEOUT);
}
public void waitForTextToContain(By locator, String targetSubstring, Duration timeout) {
webUtils.waitForCondition(timeout, ExpectedConditions.textToBePresentInElementLocated(locator, targetSubstring));
}
public void waitUntilElementDisappears(By selector) {
waitUntilElementDisappears(selector, config.getTimeout().LONG_WAIT_TIMEOUT, config.getTimeout().LONG_POLLING);
}
public void waitUntilElementDisappears(By selector, Duration timeout, Duration polling) {
try {
screenShotHelper.takesScreenshotOnAction("Wait for element [" + selector + "] to disappear.");
webUtils.waitForFunction(x -> getDriver().findElements(selector).size() == 0, timeout, polling);
} catch (Exception e) {
screenShotHelper.takesScreenshotOnError("Element [" + selector + "] did not disappear.", e);
throw e;
}
}
}