From 1a062efc3e25f86176b839aaabd28e9667a3e07b Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sat, 23 Jun 2012 16:41:47 +0200 Subject: [PATCH] added selenium test case for authentication --- scm-webapp/pom.xml | 123 ++++++++ .../resources/js/login/sonia.login.form.js | 1 + .../scm/selenium/AuthenticationITCase.java | 57 ++++ .../sonia/scm/selenium/SeleniumTestBase.java | 270 ++++++++++++++++++ 4 files changed, 451 insertions(+) create mode 100644 scm-webapp/src/test/java/sonia/scm/selenium/AuthenticationITCase.java create mode 100644 scm-webapp/src/test/java/sonia/scm/selenium/SeleniumTestBase.java diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 52c456c6a8..96a902f54c 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -231,6 +231,20 @@ + + org.seleniumhq.selenium + selenium-java + 2.24.1 + test + + + + org.seleniumhq.selenium + selenium-firefox-driver + 2.24.1 + test + + com.jcraft jsch @@ -435,6 +449,11 @@ org.apache.maven.plugins maven-failsafe-plugin 2.12 + + + sonia/scm/it/*ITCase.java + + integration-test @@ -499,6 +518,110 @@ + + selenium + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.12 + + + sonia/scm/selenium/*ITCase.java + + + + + integration-test + + integration-test + + + + verify + + verify + + + + + + + org.mortbay.jetty + maven-jetty-plugin + 6.1.26 + + 8086 + STOP + + + scm.home + target/scm-it + + + + + 8082 + 60000 + + + ${project.build.javaLevel} + ${project.build.javaLevel} + ${project.build.sourceEncoding} + 0 + true + + + + start-jetty + pre-integration-test + + deploy-war + + + + stop-jetty + post-integration-test + + stop + + + + + + + org.codehaus.mojo + selenium-maven-plugin + 2.3 + + + start-selenium-server + pre-integration-test + + start-server + + + true + + + + stop-selenium-server + post-integration-test + + stop-server + + + + + + + + + + doc diff --git a/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js b/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js index c4ed773987..22d037d6a2 100644 --- a/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js +++ b/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js @@ -82,6 +82,7 @@ Sonia.login.Form = Ext.extend(Ext.FormPanel,{ scope: this, handler: this.cancel },{ + id: 'loginButton', text: this.loginText, formBind: true, scope: this, diff --git a/scm-webapp/src/test/java/sonia/scm/selenium/AuthenticationITCase.java b/scm-webapp/src/test/java/sonia/scm/selenium/AuthenticationITCase.java new file mode 100644 index 0000000000..105fbb1100 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/selenium/AuthenticationITCase.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. 3. Neither the name of SCM-Manager; + * nor the names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.selenium; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +/** + * + * @author Sebastian Sdorra + */ +public class AuthenticationITCase extends SeleniumTestBase +{ + + /** + * Method description + * + * + * @throws Exception + */ + @Test + public void testAuthentication() throws Exception + { + authenticate("scmadmin", "scmadmin"); + logout(); + } +} diff --git a/scm-webapp/src/test/java/sonia/scm/selenium/SeleniumTestBase.java b/scm-webapp/src/test/java/sonia/scm/selenium/SeleniumTestBase.java new file mode 100644 index 0000000000..356c77fdba --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/selenium/SeleniumTestBase.java @@ -0,0 +1,270 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. 3. Neither the name of SCM-Manager; + * nor the names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.selenium; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.io.Files; + +import org.junit.After; +import org.junit.Before; + +import org.openqa.selenium.By; +import org.openqa.selenium.OutputType; +import org.openqa.selenium.TakesScreenshot; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.firefox.FirefoxDriver; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.IOException; + +import java.util.concurrent.TimeUnit; + +/** + * + * @author Sebastian Sdorra + */ +public class SeleniumTestBase +{ + + /** + * the logger for SeleniumTestBase + */ + private static final Logger logger = + LoggerFactory.getLogger(SeleniumTestBase.class); + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @throws Exception + */ + @After + public void tearDown() throws Exception + { + driver.quit(); + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @throws Exception + */ + @Before + public void setUp() throws Exception + { + driver = new FirefoxDriver(); + baseUrl = "http://localhost:8082/scm/"; + open("index.html"); + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param username + * @param password + */ + protected void authenticate(String username, String password) + { + type("input[name=username]", username); + type("input[name=password]", password); + waitAndClick("#loginButton button"); + + String ue = waitForPresence("#scm-userinfo-tip").getText(); + + assertEquals(username, ue); + } + + /** + * Method description + * + */ + protected void logout() + { + waitAndClick("#navLogout a"); + } + + /** + * Method description + * + * + * @param url + */ + protected void open(String url) + { + driver.get(baseUrl + url); + pause(500, TimeUnit.MILLISECONDS); + } + + /** + * Method description + * + * + * @param value + * @param unit + */ + protected void pause(int value, TimeUnit unit) + { + driver.manage().timeouts().implicitlyWait(value, unit); + } + + /** + * Method description + * + * + * @param target + */ + protected void screenshot(String target) + { + screenshot(new File(target)); + } + + /** + * Method description + * + * + * @param target + */ + protected void screenshot(File target) + { + try + { + File scrFile = + ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); + + Files.copy(scrFile, target); + } + catch (IOException ex) + { + logger.error("could not create screenshot", ex); + } + } + + /** + * Method description + * + * + * @param cssSelector + * + * @return + */ + protected WebElement select(String cssSelector) + { + WebElement element = driver.findElement(By.cssSelector(cssSelector)); + + assertNotNull(element); + + return element; + } + + /** + * Method description + * + * + * @param cssLocator + * @param value + */ + protected void type(String cssLocator, String value) + { + select(cssLocator).clear(); + select(cssLocator).sendKeys(value); + } + + /** + * Method description + * + * + * @param query + */ + protected void waitAndClick(String query) + { + waitToBeClickable(query).click(); + } + + /** + * Method description + * + * + * @param query + * + * @return + */ + protected WebElement waitForPresence(String query) + { + WebDriverWait wait = new WebDriverWait(driver, 2); + + return wait.until( + ExpectedConditions.presenceOfElementLocated(By.cssSelector(query))); + } + + /** + * Method description + * + * + * @param query + * + * @return + */ + protected WebElement waitToBeClickable(String query) + { + WebDriverWait wait = new WebDriverWait(driver, 2); + + return wait.until( + ExpectedConditions.elementToBeClickable(By.cssSelector(query))); + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + protected WebDriver driver; + + /** Field description */ + private String baseUrl; +}