package com.gfk.senbot.framework.services.selenium; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.IOException; import org.apache.commons.lang.StringUtils; import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.support.ui.ExpectedConditions; import org.springframework.util.ResourceUtils; import com.gfk.senbot.framework.BaseServiceHub; import com.gfk.senbot.framework.context.SenBotContext; /** * A selenium util class for all navigation related actions * * @author joostschouten * */ public class NavigationService extends BaseServiceHub { private final ElementService seleniumElementService; /** * Constructor * * @param seleniumElementService A ElementService object */ public NavigationService(ElementService seleniumElementService) { this.seleniumElementService = seleniumElementService; } /** * Navigates the {@link WebDriver} to the passed page * * @param url to navigate to. This can be either a file on the file system, a http(s) url or a {@link ResourceUtils#CLASSPATH_URL_PREFIX} prefixed * string indicating the page can be found on the current classpath. * @throws IOException */ public void navigate_to_url(String url) throws IOException { if (url.startsWith(SenBotContext.RESOURCE_LOCATION_PREFIX)) { String urlLoc = getSenBotContext().getRuntimeResources() + url.replace(SenBotContext.RESOURCE_LOCATION_PREFIX, ""); if (urlLoc.startsWith("/")) { urlLoc = urlLoc.replaceFirst("/", ""); } url = "file:///" + urlLoc; } getWebDriver().get(url); } /** * Check if the current page viewed by the {@link WebDriver} matches that of the passed url. If the expectedPage holds url parameters * they will be used to match on. If none are provided but the current page does have them, the parameters on the current page will be ignored in the match * @param exectedPage */ public void isCurrentlyOnPage(String exectedPage) { if (exectedPage.endsWith("/")) { exectedPage = exectedPage.substring(0, exectedPage.length() - 1); } try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } String currentPage = getWebDriver().getCurrentUrl(); if (currentPage.contains("?") && !exectedPage.contains("?")) { currentPage = currentPage.substring(0, currentPage.indexOf("?")); } if (currentPage.endsWith("/")) { currentPage = currentPage.substring(0, currentPage.length() - 1); } assertEquals(exectedPage, currentPage); } /** * Find a Element that has a attribute with a certain value and click it * * @param attributeName * @param attributeValue */ public void clickElementWithAttributeValue(String attributeName, String attributeValue) { By xpath = By.xpath("//*[@" + attributeName + "='" + attributeValue + "']"); WebElement element = seleniumElementService.findExpectedElement(xpath); assertTrue("The element you are trying to click (" + xpath.toString() + ") is not displayed", element.isDisplayed()); element.click(); } /** * find and click a button or input containing the passed text. Will return the first match where an input take presedence * over a button * @param text which should be contained on the button * @throws AssertionError if no button with this text is found * */ public void clickButtonWithText(String text) { String caseInsensitiveButtonText = seleniumElementService.constructCaseInsensitiveContains("text()", text); By buttonPpath = By.xpath("//button[" + caseInsensitiveButtonText + "]"); String caseInsensitiveValueText = seleniumElementService.constructCaseInsensitiveContains("@value", text); By submitPath = By.xpath("//input[@type='submit'][" + caseInsensitiveValueText + "]"); By inputButtonPath = By.xpath("//input[@type='button'][" + caseInsensitiveValueText + "]"); By inputResetPath = By.xpath("//input[@type='reset'][" + caseInsensitiveValueText + "]"); WebElement foundButton = seleniumElementService.findExpectedFirstMatchedElement(buttonPpath, submitPath, inputButtonPath, inputResetPath); if (foundButton == null) { foundButton = seleniumElementService.findExpectedFirstMatchedElement(2, buttonPpath, submitPath, inputButtonPath, inputResetPath); } foundButton.click(); } /** * Has a page been requested for this selenium session. This method is available to prevent scripts for waiting for a cetrain condition * if no url has been requested yet. If true you know you can just proceed and not check for any state as none exists * @return {@link Boolean} */ public boolean isInitialPageRequested() { String currentUrl = getWebDriver().getCurrentUrl(); if (StringUtils.isBlank(currentUrl) || ( !currentUrl.toLowerCase().startsWith("http") && !currentUrl.toLowerCase().startsWith("file") ) ) { return false; } else { return true; } } /** * Hovers the mouse over the given element * @param locator The element locator */ public void mouseHoverOverElement(By locator) { SynchronisationService synchronisationService = new SynchronisationService(); synchronisationService.waitAndAssertForExpectedCondition(ExpectedConditions.visibilityOfElementLocated(locator)); WebElement element = getWebDriver().findElement(locator); Actions builder = new Actions(getWebDriver()); Actions hoverOverRegistrar = builder.moveToElement(element); hoverOverRegistrar.perform(); } public void windowScrollBottom() { JavascriptExecutor js = (JavascriptExecutor) getWebDriver(); js.executeScript("window.scrollTo(0, document.body.scrollHeight)"); } public void windowScrollTop() { JavascriptExecutor js = (JavascriptExecutor) getWebDriver(); js.executeScript("window.scrollTo(0, 0)"); } public void scrollElementIntoView(WebElement element) { JavascriptExecutor js = (JavascriptExecutor) getWebDriver(); js.executeScript("arguments[0].scrollIntoView();", element); } }