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    
017    package edu.samplu.common;
018    
019    import com.thoughtworks.selenium.SeleneseTestBase;
020    import org.junit.After;
021    import org.junit.AfterClass;
022    import org.junit.Before;
023    import org.junit.BeforeClass;
024    import org.openqa.selenium.Alert;
025    import org.openqa.selenium.By;
026    import org.openqa.selenium.JavascriptExecutor;
027    import org.openqa.selenium.WebDriver;
028    import org.openqa.selenium.chrome.ChromeDriverService;
029    
030    import java.util.ArrayList;
031    import java.util.List;
032    import java.util.Set;
033    import java.util.concurrent.TimeUnit;
034    
035    import static com.thoughtworks.selenium.SeleneseTestBase.fail;
036    import 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     */
043    public 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.login(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