package org.syftkog.web.test.framework; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import org.apache.commons.io.FileUtils; import static org.syftkog.web.test.framework.StepLogger.TRACE; import org.openqa.selenium.OutputType; import org.openqa.selenium.SearchContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.Assert; /** * * @author BenjaminLimb * @param <T> */ public class Page<T extends Page> implements HasDriver, HasSearchContext { /** * */ public static final Logger LOG = LoggerFactory.getLogger(Page.class); private final Driver driver; private final SearchContext searchContext; private final String url; private final PageAssertions<T> assertThatPage = new PageAssertions<>((T) this); private final PageWaits<T> waitUntil = new PageWaits<>((T) this); /** * * @return assertions for the page */ public PageAssertions<T> assertPage() { return assertThatPage; } /** * * @return page specific wait methods */ public PageWaits<T> waitUntil() { return waitUntil; } /** * * @return this (for chaining methods) */ public T waitUntilLoaded() { return waitUntil().loaded(); } /** * * @return are all the overridable load conditions met? */ public Boolean isLoadConditionMet() { return true; } /** * * @param hasDriver * @param url * */ public Page(HasDriver hasDriver, String url) { this.driver = hasDriver.getDriver(); this.searchContext = hasDriver.getDriver(); this.url = url; } /** * * @param hasDriver * @param hasSearchContext * @param url * */ public Page(HasDriver hasDriver, HasSearchContext hasSearchContext, String url) { this.driver = hasDriver.getDriver(); this.searchContext = hasSearchContext.getSearchContext(); this.url = url; } /** * * @return */ @Override public Driver getDriver() { return driver; } /** * * @return */ public T addPageToDriverHistory() { getDriver().addPageToDriverHistory(this); return (T) this; } /** * * @return */ public T load() { navigateTo(); waitUntil.loaded(); return (T) this; } /** * * @return */ public T navigateTo() { getDriver().logStep("GOTO: \"" + url + "\""); String navURL = url; try { URL urlA = new URL(navURL); getDriver().navigate().to(urlA); getDriver().addPageToDriverHistory(this); } catch (MalformedURLException ex) { throw new RuntimeException(ex); } return (T) this; } /** * * @return */ public T prepareToNavigateToNewUrl() { getDriver().prepareToNavigateToNewUrl(); return (T) this; } /** * * @return */ public T waitForNavigateToNewUrl() { getDriver().waitForNavigateToNewUrl(); return (T) this; } /** * * @return */ public String getUrl() { return url; } /** * * @return */ public T refreshPage() { getDriver().navigate().refresh(); waitUntil.loaded(); return (T) this; } /** * * @return */ public Boolean isDocumentReadyState() { return executeJavascript(("return document.readyState")).equals("complete"); } /** * * @return */ public Boolean isCorrectPage() { try { URL currentURL = new URL(getDriver().getCurrentUrl()); String actualPath = currentURL.getPath(); String expectedPath = new URL(url).getPath(); getDriver().getStepLogger().log(TRACE, "IsCorrectPage returning \"" + actualPath.contains(expectedPath) + "\" ActualURL\"" + currentURL.toString() + "\" ExpectedPath:\"" + expectedPath + "\""); return actualPath.contains(expectedPath); } catch (MalformedURLException ex) { throw new RuntimeException(ex); } } /** * * @return */ public Boolean isJQueryInactive() { return (Long) executeJavascript("return jQuery.active") == 0; } /** * * @return */ public Long jQueryActiveCount() { return (Long) executeJavascript("return jQuery.active"); } /** * * @return - whether the driver is on the expected URL and all overridable load conditions are met. */ public Boolean isLoaded() { Assert.assertNotNull(url, "isLoaded cannot be called without having a URL to check against."); return isCorrectPage() && isLoadConditionMet(); } /** * * @param script * @return */ public Object executeJavascript(String script) { getDriver().getStepLogger().log(TRACE, "Execute Javascript: " + script); Object ob = getDriver().executeScript(script); getDriver().getStepLogger().log(TRACE, "Javascript returned:" + ((ob == null) ? "null" : ob.toString())); return ob; } /** * Returns the number of active jQuery AJAX requests. * * @see http://hustoknow.blogspot.com/2010/10/how-jqueryactive-code-works.html * @return number of active jQuery AJAX requests */ public Integer getJQueryPendingAJAXRequests() { //TODO: wrap this in a try catch and return null if jquery is not defined. int active = Integer.parseInt(executeJavascript("return jQuery.active").toString()); return active; } /** * takeScreenShot takes a screen shot of the current browser and saves it as a * png. * * @param fileNamePNG */ public void takeScreenShot(String fileNamePNG) { LOG.info("Saved screenshot to file " + fileNamePNG); File scrFile = getDriver().getScreenshotAs(OutputType.FILE); try { FileUtils.copyFile(scrFile, new File(fileNamePNG)); } catch (IOException e) { throw new RuntimeException(e); } } /** * * @return */ @Override public SearchContext getSearchContext() { return searchContext; } }