View Javadoc
1   package org.itracker.selenium;
2   
3   import com.google.common.base.Function;
4   import org.apache.log4j.Logger;
5   import org.itracker.AbstractDependencyInjectionTest;
6   import org.openqa.selenium.*;
7   import org.openqa.selenium.support.ui.FluentWait;
8   import org.subethamail.wiser.Wiser;
9   
10  import java.util.concurrent.TimeUnit;
11  
12  /**
13   * It is a base class for all Selenium-based test cases.
14   * It performs initialization of Selenium client part and
15   * retrieves some generally-used parameters like hose application
16   * is running at, port, context.
17   *
18   * @author Andrey Sergievskiy <seas@andreysergievskiy.com>
19   */
20  public abstract class AbstractSeleniumTestCase
21          extends AbstractDependencyInjectionTest {
22      public final static String SE_TIMEOUT = "2000";
23      protected static final Wiser wiser;
24  
25      protected WebDriver driver;
26      protected String applicationHost;
27      protected int applicationPort;
28      protected String applicationPath;
29      protected String applicationURL;
30      Logger log = Logger.getLogger(getClass());
31  
32      static {
33          wiser = new Wiser(SeleniumManager.getSMTPPort());
34          wiser.start();
35          Logger.getLogger(AbstractSeleniumTestCase.class).info("started wiser on " + wiser.getServer().getPort());
36  
37          Runtime.getRuntime().addShutdownHook(new Thread() {
38              public void run() {
39                  try {
40                      wiser.stop();
41                      Logger.getLogger(getClass()).info("stopped wiser " + wiser);
42                  } catch (RuntimeException e) {
43                      Logger.getLogger(getClass()).warn("could not stop running wiser: " + wiser);
44                      Logger.getLogger(getClass()).debug("exception caught", e);
45                  }
46              }
47          });
48      }
49  
50      @Override
51      public void onSetUp() throws Exception {
52          super.onSetUp();
53          driver = SeleniumManager.getWebDriver();
54          assertNotNull("driver", driver);
55          driver.manage().timeouts().implicitlyWait(Long.valueOf(SE_TIMEOUT), TimeUnit.MILLISECONDS);
56          applicationHost = SeleniumManager.getApplicationHost();
57          applicationPort = SeleniumManager.getApplicationPort();
58          applicationPath = SeleniumManager.getApplicationPath();
59          applicationURL = "http://" + applicationHost + ":" + applicationPort + "/"
60                  + applicationPath;
61      }
62  
63      final WebElement assertElementPresent(By by) {
64          assertTrue(driver.getCurrentUrl() + " " + by + " present", isElementPresent(by));
65          log.debug("element present by " + by);
66          return driver.findElement(by);
67      }
68  
69      final void assertElementNotPresent(By by) {
70          assertFalse(driver.getCurrentUrl() + " " + by + " present", isElementPresent(by));
71          log.debug("element not present by " + by);
72      }
73  
74      final WebElement assertElementTextEquals(String expected, By by) {
75          WebElement el = assertElementPresent(by);
76          assertEquals(driver.getCurrentUrl() + " " + by, expected, el.getText());
77          log.debug("text equals '" + expected + "' by " + by);
78          return el;
79      }
80  
81      final void assertElementCountEquals(int expected, By by) {
82          assertEquals(driver.getCurrentUrl() + " " + by + " size", expected, driver.findElements(by).size());
83          log.debug("element count '" + expected + "' by " + by);
84      }
85  
86  
87      /**
88       * This will initialize a new selenium session for this test scope.
89       */
90      protected void closeSession() {
91          SeleniumManager.closeSession(driver);
92      }
93  
94      /**
95       * Assert being on login page and enter the credentials.
96       * <p>Success will be asserted with <code>itracker</code> Cookie present.</p>
97       */
98      protected final void login(final String username, final String password) {
99  
100         log.debug("login called with " + username + ", " + password);
101 
102         assertElementPresent(By.name("login")).sendKeys(username);
103         assertElementPresent(By.name("password")).sendKeys(password);
104         assertElementPresent(By.xpath("//*[@value='Login']")).click();
105         waitForPageToLoad();
106 
107         assertNotNull("Login failed: 'itracker' Cookie was not found", driver.manage().getCookieNamed("itracker"));
108 
109         log.debug("loginUser, logged in " + username + ", cookies: " + driver.manage().getCookies());
110     }
111 
112     private boolean isElementPresent(By by) {
113       try {
114         driver.manage().timeouts().implicitlyWait(200, TimeUnit.MILLISECONDS);
115         driver.findElement(by);
116         return true;
117       } catch (NoSuchElementException e) {
118         return false;
119       } finally {
120           driver.manage().timeouts().implicitlyWait(Long.valueOf(SE_TIMEOUT), TimeUnit.MILLISECONDS);
121       }
122 
123     }
124     protected void waitForPageToLoad() {
125         waitForPageToLoad(Long.valueOf(SE_TIMEOUT));
126     }
127     protected void waitForPageToLoad(long timeout) {
128 
129         new FluentWait<WebDriver>(driver)
130                 .withTimeout(timeout, TimeUnit.MILLISECONDS)
131                 .pollingEvery(200, TimeUnit.MILLISECONDS)
132                 .until(new Function<WebDriver, Boolean>() {
133                     @Override
134                     public Boolean apply(WebDriver webDriver) {
135                         try {
136                           Object result = ((JavascriptExecutor) driver).executeScript(
137                               "return 'complete' == document.readyState;");
138 
139                           if (result != null && result instanceof Boolean && (Boolean) result) {
140                             return true;
141                           }
142                         } catch (Exception e) {
143                           // Possible page reload. Fine
144                         }
145                         return false;
146                     }
147                 });
148     }
149     @Override
150     final protected String[] getConfigLocations() {
151         return new String[]{"selenium-it-application-context.xml"};
152     }
153 }