001/*
002 * Copyright 2005-2013 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package edu.samplu.common;
018
019import com.thoughtworks.selenium.SeleneseTestBase;
020import org.junit.After;
021import org.junit.AfterClass;
022import org.junit.Before;
023import org.junit.BeforeClass;
024import org.openqa.selenium.Alert;
025import org.openqa.selenium.By;
026import org.openqa.selenium.JavascriptExecutor;
027import org.openqa.selenium.WebDriver;
028import org.openqa.selenium.chrome.ChromeDriverService;
029
030import java.util.ArrayList;
031import java.util.List;
032import java.util.Set;
033import java.util.concurrent.TimeUnit;
034
035import static com.thoughtworks.selenium.SeleneseTestBase.fail;
036import static org.junit.Assert.assertEquals;
037
038/**
039 * Base class for Selenium Webdriver integration tests
040 *
041 * @author Kuali Rice Team (rice.collab@kuali.org)
042 */
043public abstract class WebDriverITBase {
044
045    public WebDriver driver;
046    static ChromeDriverService chromeDriverService;
047
048    /**
049     * Returns the URL to be used with this test
050     *
051     * @return URL of the test
052     */
053    public abstract String getTestUrl();
054
055    /**
056     * Override in test to define a user other than admin
057     * @return
058     */
059    public String getUserName() {
060        return "admin";
061    }
062
063    @BeforeClass
064    public static void createAndStartService() throws Exception {
065        chromeDriverService = WebDriverUtil.chromeDriverCreateCheck();
066        if (chromeDriverService != null) chromeDriverService.start();
067    }
068
069
070    /**
071     * Setup the WebDriver test, login and load the tested web page
072     *
073     * @throws Exception
074     */
075    @Before
076    public void setUp() throws Exception {
077        driver = WebDriverUtil.setUp(getUserName(), ITUtil.getBaseUrlString() + "/" + getTestUrl());
078        WebDriverUtil.loginKradOrKns(driver, getUserName(), new Failable() {
079            @Override
080            public void fail(String message) {
081                SeleneseTestBase.fail(message);
082            }
083        });
084    }
085
086    /**
087     * Tear down the WebDriver test
088     *
089     * @throws Exception
090     */
091    @After
092    public void tearDown() throws Exception {
093        if (ITUtil.dontTearDownPropertyNotSet()) {
094            driver.quit(); // TODO not tested with chrome, the service stop might need this check too
095        }
096    }
097
098    /**
099     * Tear down the WebDriver test
100     *
101     * @throws Exception
102     */
103    @AfterClass
104    public static void stopService() throws Exception {
105        if (chromeDriverService != null) {
106            chromeDriverService.stop();
107        }
108    }
109
110    /**
111     * Check if an element is present
112     *
113     * <p>
114     * This test takes a while due to the 'implicit wait' time.
115     * </p>
116     *
117     * @param by The locating mechanism of the element
118     * @return true if the element is present, false otherwise
119     */
120    public boolean isElementPresent(By by) {
121        if (driver.findElements(by).isEmpty()) {
122            return false;
123        } else {
124            return true;
125        }
126    }
127
128    /**
129     * Quickly check if an element is present
130     *
131     * <p>
132     * Just like {@link #isElementPresent(org.openqa.selenium.By)} but with a short 'implicit wait' time.  Use this only
133     * if it is guaranteed that all elements are rendered.
134     * </p>
135     *
136     * @param by The locating mechanism of the element
137     * @return true if the element is present, false otherwise
138     */
139    public boolean isElementPresentQuick(By by) {
140        driver.manage().timeouts().implicitlyWait(WebDriverUtil.SHORT_IMPLICIT_WAIT_TIME, TimeUnit.SECONDS);
141        boolean result = isElementPresent(by);
142        driver.manage().timeouts().implicitlyWait(WebDriverUtil.DEFAULT_IMPLICIT_WAIT_TIME, TimeUnit.SECONDS);
143        return result;
144    }
145
146    /**
147     * Assert that clicking an element causes a popup window with a specific URL
148     *
149     * @param by The locating mechanism of the element to be clicked
150     * @param windowName The name of the popup window
151     * @param url The URL of the popup window
152     */
153    public void assertPopUpWindowUrl(By by, String windowName, String url) {
154        driver.findElement(by).click();
155        String parentWindowHandle = driver.getWindowHandle();
156        // wait page to be loaded
157        driver.switchTo().window(windowName).findElements(By.tagName("head"));
158        assertEquals(url, driver.getCurrentUrl());
159        driver.switchTo().window(parentWindowHandle);
160    }
161    
162    /**
163     * 
164     *
165     * @param by The locating mechanism of the element
166    */
167    protected void waitFor(By by) throws InterruptedException {
168        waitFor(by, "");
169    }
170
171    /**
172     * 
173     *
174     * @param by The locating mechanism of the element
175     * @param message User defined message to display
176     */
177    protected void waitFor(By by, String message) throws InterruptedException {
178//        for (int second = 0;; second++) {
179            Thread.sleep(1000);
180//            if (second >= DEFAULT_WAIT_SEC) fail(by.toString() + " " + message + " " + DEFAULT_WAIT_SEC + " sec timeout.");
181            try { driver.findElement(by);
182                //break;
183            } catch (Exception e) {}
184//        }
185    }
186
187    /**
188     * 
189     *
190     * @param by The locating mechanism of the element
191     * @param text The text to type
192    */
193    protected void waitAndType(By by, String text) throws InterruptedException {
194        waitFor(by, "");
195        try {
196            (driver.findElement(by)).sendKeys(text);
197        } catch (Exception e) {
198            fail(e.getMessage() + " " + by.toString() + " " + text);
199            e.printStackTrace();
200        }
201    }
202    
203    /**
204     * 
205     *
206     * @param by The locating mechanism of the element
207     * @param text The text to type
208     * @param message User defined message to display
209    */
210    protected void waitAndType(By by, String text, String message) throws InterruptedException {
211        waitFor(by, "");
212        try {
213            (driver.findElement(by)).sendKeys(text);
214        } catch (Exception e) {
215            fail(e.getMessage() + " " + by.toString() + " " + text + "  "+message);
216            e.printStackTrace();
217        }
218    }
219    
220    /**
221     * 
222     *
223     * @param locator The locating mechanism of the element
224     * @param text The text to type
225    */
226    protected void waitAndTypeByXpath(String locator, String text) throws InterruptedException {
227        waitAndType(By.xpath(locator), text);
228    }
229    
230    /**
231     * 
232     *
233     * @param locator The locating mechanism of the element
234     * @param text The text to type
235     * @param message User defined message to display
236    */
237    protected void waitAndTypeByXpath(String locator, String text, String message) throws InterruptedException {
238        waitAndType(By.xpath(locator), text, message);
239    }
240    
241    /**
242     * 
243     *
244     * @param name The name of the element
245     * @param text The text to type
246    */
247    protected void waitAndTypeByName(String name, String text) throws InterruptedException {
248        waitAndType(By.name(name), text);
249    }
250    
251    /**
252     * Clear the text written in an input field by name of an element
253     *
254     * @param name The name of the element
255    */
256    protected void clearTextByName(String name) throws InterruptedException {
257        clearText(By.name(name));
258    }
259    
260    /**
261     * Clear the text written in an input field by xpath of an element
262     *
263     * @param locator The locating mechanism of the element
264    */
265    protected void clearTextByXpath(String locator) throws InterruptedException {
266        clearText(By.xpath(locator));
267    }
268    
269    /**
270     * Clear the text written in an input field by xpath of an element
271     *
272     * @param by method used for finding the element
273    */
274    protected void clearText(By by)  throws InterruptedException {
275        driver.findElement(by).clear();        
276    }
277    
278    /**
279     * Dismiss the javascript alert (clicking Cancel)
280     *
281    */
282    protected void dismissAlert()
283    {
284        Alert alert = driver.switchTo().alert();
285        //update is executed
286        alert.dismiss();
287    }
288    
289    /**
290     * Accept the javascript alert (clicking OK)
291     *
292    */
293    protected void acceptAlert()
294    {
295        Alert alert = driver.switchTo().alert();
296        //update is executed
297        alert.accept();
298    }
299    
300    protected String getEval(String script)
301    {
302        JavascriptExecutor js = (JavascriptExecutor) driver;
303        return (String)js.executeScript(script);
304    }
305    
306    /**
307     * Switch to new window
308     *
309    */
310    protected void switchWindow()
311    {
312        Set<String> winSet = driver.getWindowHandles();
313        List<String> winList = new ArrayList<String>(winSet);
314        String newTab = winList.get(winList.size() - 1);
315        driver.switchTo().window(newTab);
316    }
317    
318    /**
319     * Get value of any attribute by using element name
320     *
321     *@param name name of an element
322     *@param attribute the name of an attribute whose value is to be retrieved
323    */
324    protected String getAttributeByName(String name,String attribute) throws InterruptedException {
325        return getAttribute(By.name(name),attribute);
326    }
327    
328    /**
329     * Get value of any attribute by using element xpath
330     *
331     *@param locator locating mechanism of an element
332     *@param attribute the name of an attribute whose value is to be retrieved
333    */
334    protected String getAttributeByXpath(String locator,String attribute) throws InterruptedException {
335        return getAttribute(By.xpath(locator),attribute);
336    }
337    
338    /**
339     * Get value of any attribute of an element
340     *
341     * @param by method used for finding the element
342     *@param attribute the name of an attribute whose value is to be retrieved
343    */
344    protected String getAttribute(By by,String attribute)  throws InterruptedException {
345        return driver.findElement(by).getAttribute(attribute);        
346    }
347    
348    /**
349     * 
350     *
351     * @param text text of the link
352    */
353    protected void waitAndClickByLinkText(String text) throws InterruptedException {
354        waitAndClick(By.linkText(text),"");
355    }
356
357    /**
358     * 
359     *
360     * @param text text of the link
361     * @param message user defined message to display
362    */
363    protected void waitAndClickByLinkText(String text, String message) throws InterruptedException {
364        waitAndClick(By.linkText(text), message);
365    }
366    
367    /**
368     * 
369     *
370     * @param by method used for finding the element
371    */
372    protected void waitAndClick(By by) throws InterruptedException {
373        waitAndClick(by, "");
374    }
375
376    /**
377     * 
378     *
379     * @param by method used for finding the element
380     * @param message user defined message to display
381    */
382    protected void waitAndClick(By by, String message) throws InterruptedException {
383        waitFor(by, message);
384        try {
385            (driver.findElement(by)).click();
386        } catch (Exception e) {
387            fail(e.getMessage() + " " + by.toString() + " " + message);
388            e.printStackTrace();
389        }
390    }
391    
392    /**
393     * 
394     *
395     * @param locator mechanism to locate element by xpath
396    */
397    protected void waitAndClick(String locator) throws InterruptedException {
398        waitAndClick(locator, "");
399    }
400    
401    /**
402     * 
403     *
404     * @param locator mechanism to locate element by xpath
405     * @param message user defined message to display
406    */
407    protected void waitAndClick(String locator, String message) throws InterruptedException {
408        waitAndClick(By.cssSelector(locator), message);
409    }
410
411    /**
412     * 
413     *
414     * @param locator mechanism to locate element by xpath
415    */
416    protected void waitForElementPresent(String locator) throws InterruptedException {
417        waitFor(By.cssSelector(locator));
418    }
419
420    /**
421     * 
422     *
423     * @param locator mechanism to locate element by xpath
424    */    
425    protected void waitForElementPresentByXpath(String locator) throws InterruptedException {
426        waitFor(By.xpath(locator));
427    }
428    
429    /**
430     * 
431     *
432     * @param name name of an element
433    */ 
434    protected void waitForElementPresentByName(String name) throws InterruptedException {
435        waitFor(By.name(name));
436    }
437    
438    protected void checkForIncidentReport(Failable failable) {
439        checkForIncidentReport("", failable, "");
440    }
441
442    protected void checkForIncidentReport(String locator, Failable failable) {
443        checkForIncidentReport(locator, failable, "");
444    }
445    
446    protected void checkForIncidentReport(String locator, Failable failable, String message) {
447        ITUtil.checkForIncidentReport(driver.getPageSource(), locator, failable, message);
448    }
449
450
451}
452