001/**
002 * Copyright 2005-2016 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 */
016package org.kuali.rice.testtools.selenium;
017
018import com.thoughtworks.selenium.SeleneseTestBase;
019import org.junit.After;
020import org.junit.AfterClass;
021import org.junit.Before;
022import org.junit.BeforeClass;
023import org.kuali.rice.testtools.common.JiraAwareFailable;
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
035/**
036 * @author Kuali Rice Team (rice.collab@kuali.org)
037 * @deprecated see WebDriverAftBase
038 */
039public abstract class WebDriverITBase {
040
041    public WebDriver driver;
042    static ChromeDriverService chromeDriverService;
043
044    /**
045     * Returns the URL to be used with this test
046     *
047     * @return URL of the test
048     */
049    public abstract String getTestUrl();
050
051    /**
052     * Override in test to define a user other than admin
053     * @return
054     */
055    public String getUserName() {
056        return "admin";
057    }
058
059    @BeforeClass
060    public static void createAndStartService() throws Exception {
061        chromeDriverService = WebDriverUtils.chromeDriverCreateCheck();
062        if (chromeDriverService != null) chromeDriverService.start();
063    }
064
065
066    /**
067     * <p>
068     * Logs in using the KRAD Login Page, if the JVM arg remote.autologin is set, auto login as admin will not be done.
069     * </p>
070     *
071     * @param driver to login with
072     * @param userName to login with
073     * @param failable to fail on if there is a login problem
074     * @throws InterruptedException
075     */
076    public void login(WebDriver driver, String userName, JiraAwareFailable failable) throws InterruptedException {
077        if ("true".equalsIgnoreCase(System.getProperty(WebDriverUtils.REMOTE_AUTOLOGIN_PROPERTY, "true"))) {
078            driver.findElement(By.name("login_user")).clear();
079            driver.findElement(By.name("login_user")).sendKeys(userName);
080            driver.findElement(By.id("Rice-LoginButton")).click();
081            Thread.sleep(1000);
082            String contents = driver.getPageSource();
083            AutomatedFunctionalTestUtils.failOnInvalidUserName(userName, contents, failable);
084            AutomatedFunctionalTestUtils.checkForIncidentReport(driver.getPageSource(), "Login",
085                    "Login failure", failable);
086        }
087    }
088
089    public void fail(String message) { // should this method be abstract or overridden, no jira aware fail?
090        SeleneseTestBase.fail(message);
091    }
092
093    /**
094     * Setup the WebDriver test, login and load the tested web page
095     *
096     * @throws Exception
097     */
098    @Before
099    public void setUp() throws Exception {
100        driver = WebDriverUtils.setUp(this.getClass().getSimpleName(), "DeprecatedWebDriverItBaseTest");
101
102        WebDriverUtils.openTestUrl(driver, WebDriverUtils.getBaseUrlString() + "/" + getTestUrl());
103
104        login(driver, getUserName(), new JiraAwareFailable() {
105            @Override
106            public void fail(String message) {
107                SeleneseTestBase.fail(message);
108            }
109
110            @Override
111            public void jiraAwareFail(String message) {
112                SeleneseTestBase.fail(message);
113            }
114
115            @Override
116            public void jiraAwareFail(String contents, String message) {
117                SeleneseTestBase.fail(contents + " " + message);
118            }
119
120            @Override
121            public void jiraAwareFail(String contents, String message, Throwable throwable) {
122                SeleneseTestBase.fail(contents + " " + message + " " + throwable.getMessage());
123            }
124        });
125    }
126
127    /**
128     * Tear down the WebDriver test
129     *
130     * @throws Exception
131     */
132    @After
133    public void tearDown() throws Exception {
134        if (WebDriverUtils.dontTearDownPropertyNotSet()) {
135            if (driver != null) {
136                driver.quit(); // TODO not tested with chrome, the service stop might need this check too
137            } else {
138                System.out.println("WebDriver was null in WebDriverUtils.tearDown()");
139            }
140        }
141    }
142
143    /**
144     * Tear down the WebDriver test
145     *
146     * @throws Exception
147     */
148    @AfterClass
149    public static void stopService() throws Exception {
150        if (chromeDriverService != null) {
151            chromeDriverService.stop();
152        }
153    }
154
155    /**
156     * Check if an element is present
157     *
158     * <p>
159     * This test takes a while due to the 'implicit wait' time.
160     * </p>
161     *
162     * @param by The locating mechanism of the element
163     * @return true if the element is present, false otherwise
164     */
165    public boolean isElementPresent(By by) {
166        if (driver.findElements(by).isEmpty()) {
167            return false;
168        } else {
169            return true;
170        }
171    }
172
173    /**
174     * Quickly check if an element is present
175     *
176     * <p>
177     * Just like {@link #isElementPresent(org.openqa.selenium.By)} but with a short 'implicit wait' time.  Use this only
178     * if it is guaranteed that all elements are rendered.
179     * </p>
180     *
181     * @param by The locating mechanism of the element
182     * @return true if the element is present, false otherwise
183     */
184    public boolean isElementPresentQuick(By by) {
185        driver.manage().timeouts().implicitlyWait(WebDriverUtils.IMPLICIT_WAIT_TIME_LOOP_MS, TimeUnit.MILLISECONDS);
186        boolean result = isElementPresent(by);
187        driver.manage().timeouts().implicitlyWait(WebDriverUtils.IMPLICIT_WAIT_TIME_SECONDS_DEFAULT, TimeUnit.SECONDS);
188        return result;
189    }
190
191    /**
192     * Assert that clicking an element causes a popup window with a specific URL
193     *
194     * @param by The locating mechanism of the element to be clicked
195     * @param windowName The name of the popup window
196     * @param url The URL of the popup window
197     */
198    public void assertPopUpWindowUrl(By by, String windowName, String url) {
199        driver.findElement(by).click();
200        String parentWindowHandle = driver.getWindowHandle();
201        // wait page to be loaded
202        driver.switchTo().window(windowName).findElements(By.tagName("head"));
203        SeleneseTestBase.assertEquals(url, driver.getCurrentUrl());
204        driver.switchTo().window(parentWindowHandle);
205    }
206    
207    /**
208     * 
209     *
210     * @param by The locating mechanism of the element
211    */
212    protected void waitFor(By by) throws InterruptedException {
213        waitFor(by, "");
214    }
215
216    /**
217     * TODO Investigate using WebDriverUtils.waitFor
218     *
219     * @param by The locating mechanism of the element
220     * @param message User defined message to display
221     */
222    protected void waitFor(By by, String message) throws InterruptedException {
223        Thread.sleep(1000);
224        try {
225            driver.findElement(by);
226        } catch (Exception e) {
227            // ignore, fail on use if required
228        }
229    }
230
231    /**
232     * 
233     *
234     * @param by The locating mechanism of the element
235     * @param text The text to type
236    */
237    protected void waitAndType(By by, String text) throws InterruptedException {
238        waitFor(by, "");
239        try {
240            (driver.findElement(by)).sendKeys(text);
241        } catch (Exception e) {
242            fail(e.getMessage() + " " + by.toString() + " " + text);
243            e.printStackTrace();
244        }
245    }
246    
247    /**
248     * 
249     *
250     * @param by The locating mechanism of the element
251     * @param text The text to type
252     * @param message User defined message to display
253    */
254    protected void waitAndType(By by, String text, String message) throws InterruptedException {
255        waitFor(by, "");
256        try {
257            (driver.findElement(by)).sendKeys(text);
258        } catch (Exception e) {
259            fail(e.getMessage() + " " + by.toString() + " " + text + "  "+message);
260            e.printStackTrace();
261        }
262    }
263    
264    /**
265     * 
266     *
267     * @param locator The locating mechanism of the element
268     * @param text The text to type
269    */
270    protected void waitAndTypeByXpath(String locator, String text) throws InterruptedException {
271        waitAndType(By.xpath(locator), text);
272    }
273    
274    /**
275     * 
276     *
277     * @param locator The locating mechanism of the element
278     * @param text The text to type
279     * @param message User defined message to display
280    */
281    protected void waitAndTypeByXpath(String locator, String text, String message) throws InterruptedException {
282        waitAndType(By.xpath(locator), text, message);
283    }
284    
285    /**
286     * 
287     *
288     * @param name The name of the element
289     * @param text The text to type
290    */
291    protected void waitAndTypeByName(String name, String text) throws InterruptedException {
292        waitAndType(By.name(name), text);
293    }
294    
295    /**
296     * Clear the text written in an input field by name of an element
297     *
298     * @param name The name of the element
299    */
300    protected void clearTextByName(String name) throws InterruptedException {
301        clearText(By.name(name));
302    }
303    
304    /**
305     * Clear the text written in an input field by xpath of an element
306     *
307     * @param locator The locating mechanism of the element
308    */
309    protected void clearTextByXpath(String locator) throws InterruptedException {
310        clearText(By.xpath(locator));
311    }
312    
313    /**
314     * Clear the text written in an input field by xpath of an element
315     *
316     * @param by method used for finding the element
317    */
318    protected void clearText(By by)  throws InterruptedException {
319        driver.findElement(by).clear();        
320    }
321    
322    /**
323     * Dismiss the javascript alert (clicking Cancel)
324     *
325    */
326    protected void dismissAlert()
327    {
328        Alert alert = driver.switchTo().alert();
329        //update is executed
330        alert.dismiss();
331    }
332    
333    /**
334     * Accept the javascript alert (clicking OK)
335     *
336    */
337    protected void acceptAlert()
338    {
339        Alert alert = driver.switchTo().alert();
340        //update is executed
341        alert.accept();
342    }
343    
344    protected String getEval(String script)
345    {
346        JavascriptExecutor js = (JavascriptExecutor) driver;
347        return (String)js.executeScript(script);
348    }
349    
350    /**
351     * Switch to new window
352     *
353    */
354    protected void switchWindow()
355    {
356        Set<String> winSet = driver.getWindowHandles();
357        List<String> winList = new ArrayList<String>(winSet);
358        String newTab = winList.get(winList.size() - 1);
359        driver.switchTo().window(newTab);
360    }
361    
362    /**
363     * Get value of any attribute by using element name
364     *
365     *@param name name of an element
366     *@param attribute the name of an attribute whose value is to be retrieved
367    */
368    protected String getAttributeByName(String name,String attribute) throws InterruptedException {
369        return getAttribute(By.name(name),attribute);
370    }
371    
372    /**
373     * Get value of any attribute by using element xpath
374     *
375     *@param locator locating mechanism of an element
376     *@param attribute the name of an attribute whose value is to be retrieved
377    */
378    protected String getAttributeByXpath(String locator,String attribute) throws InterruptedException {
379        return getAttribute(By.xpath(locator),attribute);
380    }
381    
382    /**
383     * Get value of any attribute of an element
384     *
385     * @param by method used for finding the element
386     *@param attribute the name of an attribute whose value is to be retrieved
387    */
388    protected String getAttribute(By by,String attribute)  throws InterruptedException {
389        return driver.findElement(by).getAttribute(attribute);        
390    }
391    
392    /**
393     * 
394     *
395     * @param text text of the link
396    */
397    protected void waitAndClickByLinkText(String text) throws InterruptedException {
398        waitAndClick(By.linkText(text),"");
399    }
400
401    /**
402     * 
403     *
404     * @param text text of the link
405     * @param message user defined message to display
406    */
407    protected void waitAndClickByLinkText(String text, String message) throws InterruptedException {
408        waitAndClick(By.linkText(text), message);
409    }
410    
411    /**
412     * 
413     *
414     * @param by method used for finding the element
415    */
416    protected void waitAndClick(By by) throws InterruptedException {
417        waitAndClick(by, "");
418    }
419
420    /**
421     * 
422     *
423     * @param by method used for finding the element
424     * @param message user defined message to display
425    */
426    protected void waitAndClick(By by, String message) throws InterruptedException {
427        waitFor(by, message);
428        try {
429            (driver.findElement(by)).click();
430        } catch (Exception e) {
431            fail(e.getMessage() + " " + by.toString() + " " + message);
432        }
433    }
434
435    /**
436     * 
437     *
438     * @param locator mechanism to locate element by xpath
439    */
440    protected void waitAndClick(String locator) throws InterruptedException {
441        waitAndClick(locator, "");
442    }
443    
444    /**
445     * 
446     *
447     * @param locator mechanism to locate element by xpath
448     * @param message user defined message to display
449    */
450    protected void waitAndClick(String locator, String message) throws InterruptedException {
451        waitAndClick(By.cssSelector(locator), message);
452    }
453
454    /**
455     * 
456     *
457     * @param locator mechanism to locate element by xpath
458    */
459    protected void waitForElementPresent(String locator) throws InterruptedException {
460        waitFor(By.cssSelector(locator));
461    }
462
463    /**
464     * 
465     *
466     * @param locator mechanism to locate element by xpath
467    */    
468    protected void waitForElementPresentByXpath(String locator) throws InterruptedException {
469        waitFor(By.xpath(locator));
470    }
471    
472    /**
473     * 
474     *
475     * @param name name of an element
476    */ 
477    protected void waitForElementPresentByName(String name) throws InterruptedException {
478        waitFor(By.name(name));
479    }
480    
481    protected void checkForIncidentReport(JiraAwareFailable failable) {
482        checkForIncidentReport("", failable, "");
483    }
484
485    protected void checkForIncidentReport(String locator, JiraAwareFailable failable) {
486        checkForIncidentReport(locator, failable, "");
487    }
488    
489    protected void checkForIncidentReport(String locator, JiraAwareFailable failable, String message) {
490        AutomatedFunctionalTestUtils.checkForIncidentReport(driver.getPageSource(), locator, message, failable);
491    }
492
493
494}
495