1 package org.apache.archiva.web.test.parent;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
22 import org.apache.archiva.web.test.tools.ArchivaSeleniumExecutionRule;
23 import org.apache.archiva.web.test.tools.WebdriverUtility;
24 import org.junit.Assert;
25 import org.junit.Rule;
28 import java.nio.file.Path;
29 import java.text.SimpleDateFormat;
30 import java.util.Date;
31 import java.util.Iterator;
33 import java.util.Map.Entry;
34 import java.util.Properties;
35 import java.util.concurrent.TimeUnit;
36 import java.util.function.Function;
38 import org.openqa.selenium.*;
39 import org.openqa.selenium.htmlunit.HtmlUnitDriver;
40 import org.openqa.selenium.interactions.Actions;
41 import org.openqa.selenium.support.ui.ExpectedConditions;
42 import org.openqa.selenium.support.ui.FluentWait;
43 import org.openqa.selenium.support.ui.Select;
44 import org.openqa.selenium.support.ui.WebDriverWait;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
49 * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
53 public abstract class AbstractSeleniumTest
55 private final Logger logger = LoggerFactory.getLogger( getClass() );
58 public ArchivaSeleniumExecutionRule archivaSeleniumExecutionRule = new ArchivaSeleniumExecutionRule();
60 public String browser = System.getProperty( "browser" );
62 public String baseUrl =
63 "http://localhost:" + System.getProperty( "container.http.port" ) + "/archiva/index.html?request_lang=en";
65 public int maxWaitTimeInMs = Integer.getInteger( "maxWaitTimeInMs" );
67 public String seleniumHost = System.getProperty( "seleniumHost", "localhost" );
69 public int seleniumPort = Integer.getInteger( "seleniumPort", 4444 );
71 public boolean remoteSelenium = Boolean.parseBoolean( System.getProperty( "seleniumRemote", "false" ) );
73 WebDriver webDriver = null;
78 * this method is called by the Rule before executing a test
86 p.load( this.getClass().getClassLoader().getResourceAsStream( "test.properties" ) );
88 baseUrl = WebdriverUtility.getBaseUrl()+"/index.html?request_lang=en";
90 open( baseUrl, browser, seleniumHost, seleniumPort, maxWaitTimeInMs, remoteSelenium );
95 * this method is called by the Rule after executing a tests
99 getWebDriver().close();
103 * Initialize selenium
105 public void open( String baseUrl, String browser, String seleniumHost, int seleniumPort, int maxWaitTimeInMs, boolean remoteSelenium)
110 if ( getWebDriver() == null )
112 WebDriver driver = WebdriverUtility.newWebDriver(browser, seleniumHost, seleniumPort, remoteSelenium);
114 // selenium.setTimeout( Integer.toString( maxWaitTimeInMs ) );
115 this.webDriver = driver;
118 catch ( Exception e )
121 System.out.print( e.getMessage() );
126 public void assertAdminCreated()
129 initializeArchiva( baseUrl, browser, maxWaitTimeInMs, seleniumHost, seleniumPort, remoteSelenium );
132 public void initializeArchiva( String baseUrl, String browser, int maxWaitTimeInMs, String seleniumHost,
133 int seleniumPort, boolean remoteSelenium)
137 open( baseUrl, browser, seleniumHost, seleniumPort, maxWaitTimeInMs, remoteSelenium);
139 getWebDriver().get(baseUrl);
140 WebDriverWait wait = new WebDriverWait(getWebDriver(),30);
141 wait.until(ExpectedConditions.presenceOfElementLocated(By.id("topbar-menu")));
143 FluentWait fluentWait = new FluentWait(getWebDriver()).withTimeout(10, TimeUnit.SECONDS);
144 fluentWait.until( ExpectedConditions.or(
145 ExpectedConditions.visibilityOfElementLocated(By.id("create-admin-link")),
146 ExpectedConditions.visibilityOfElementLocated(By.id("login-link-a"))));
149 // if not admin user created create one
150 if ( isElementVisible( "create-admin-link" ) )
152 Assert.assertFalse( isElementVisible( "login-link-a" ) );
153 Assert.assertFalse( isElementVisible( "register-link-a" ) );
154 // skygo need to set to true for passing is that work as expected ?
155 clickLinkWithLocator( "create-admin-link-a");
156 wait = new WebDriverWait(getWebDriver(), 5);
157 wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("user-create")));
159 String fullname = getProperty( "ADMIN_FULLNAME" );
160 String username = getAdminUsername();
161 String mail = getProperty( "ADMIN_EMAIL" );
162 String password = getProperty( "ADMIN_PASSWORD" );
163 submitAdminData( fullname, mail, password );
164 assertUserLoggedIn( username );
165 clickLinkWithLocator( "logout-link-a" , false);
169 Assert.assertTrue( isElementVisible( "login-link-a" ) );
170 Assert.assertTrue( isElementVisible( "register-link-a" ) );
171 login( getAdminUsername(), getAdminPassword() );
176 public WebDriver getWebDriver() {
177 return this.webDriver;
180 protected String getProperty( String key )
182 return p.getProperty( key );
185 public String getAdminUsername()
187 String adminUsername = getProperty( "ADMIN_USERNAME" );
188 return adminUsername;
191 public String getAdminPassword()
193 String adminPassword = getProperty( "ADMIN_PASSWORD" );
194 return adminPassword;
197 public void submitAdminData( String fullname, String email, String password )
199 setFieldValue( "fullname", fullname );
200 setFieldValue( "email", email );
201 setFieldValue( "password", password );
202 setFieldValue( "confirmPassword", password );
203 clickButtonWithLocator( "user-create-form-register-button" , false);
206 public void login( String username, String password )
208 login( username, password, true, "Login Page" );
211 public void login( String username, String password, boolean valid, String assertReturnPage )
213 if ( isElementVisible( "login-link-a" ) )//isElementPresent( "loginLink" ) )
217 submitLoginPage( username, password, false, valid, assertReturnPage );
221 assertUserLoggedIn( username );
226 public void goToLoginPage()
228 logger.info("Goto login page");
229 getWebDriver().get( baseUrl );
230 WebDriverWait wait = new WebDriverWait(getWebDriver(),30);
231 wait.until(ExpectedConditions.presenceOfElementLocated(By.id("topbar-menu")));
232 wait.until(ExpectedConditions.or(ExpectedConditions.visibilityOfElementLocated(By.id("logout-link")),
233 ExpectedConditions.visibilityOfElementLocated(By.id("login-link-a"))));
235 // are we already logged in ?
236 if ( isElementVisible( "logout-link" ) ) //isElementPresent( "logoutLink" ) )
238 logger.info("Logging out ");
240 clickLinkWithLocator( "logout-link-a", false );
242 wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("login-link-a")));
243 clickLinkWithLocator( "login-link-a", false );
244 // This is a workaround for bug with HTMLUnit. The display attribute of the
245 // login dialog is not changed via the click.
246 // TODO: Check after changing jquery, bootstrap or htmlunit version
247 if (getWebDriver() instanceof HtmlUnitDriver)
249 ( (JavascriptExecutor) getWebDriver() ).executeScript( "$('#modal-login').show();" );
252 wait = new WebDriverWait(getWebDriver(),20);
253 wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("modal-login")));
258 public void assertLoginModal()
260 assertElementPresent( "user-login-form" );
261 Assert.assertTrue( isElementVisible( "register-link" ) );
262 Assert.assertTrue( isElementVisible("user-login-form-username" ));
263 Assert.assertTrue( isElementVisible("user-login-form-password" ));
264 assertButtonWithIdPresent( "modal-login-ok" );
265 Assert.assertTrue( isElementVisible( "modal-login-ok" ));
269 public void submitLoginPage( String username, String password )
271 submitLoginPage( username, password, false, true, "Login Page" );
274 public void submitLoginPage( String username, String password, boolean validUsernamePassword )
276 submitLoginPage( username, password, false, validUsernamePassword, "Login Page" );
279 public void submitLoginPage( String username, String password, boolean rememberMe, boolean validUsernamePassword,
280 String assertReturnPage )
282 logger.info("Activating login form");
283 // clickLinkWithLocator( "login-link-a", false);
284 WebDriverWait wait = new WebDriverWait(getWebDriver(),5);
285 WebElement usernameField = wait.until(ExpectedConditions.visibilityOf(getWebDriver().findElement(By.id("user-login-form-username"))));
286 wait = new WebDriverWait(getWebDriver(),5);
287 WebElement passwordField = wait.until(ExpectedConditions.visibilityOf(getWebDriver().findElement(By.id("user-login-form-password"))));
288 wait = new WebDriverWait(getWebDriver(),5);
289 WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.id("modal-login-ok")));
290 usernameField.sendKeys(username);
291 passwordField.sendKeys(password);
295 checkField( "rememberMe" );
299 if ( validUsernamePassword )
301 assertUserLoggedIn( username );
306 if ( "Login Page".equals( assertReturnPage ) )
312 assertPage( assertReturnPage );
317 // *******************************************************
318 // Auxiliar methods. This method help us and simplify test.
319 // *******************************************************
321 protected void assertUserLoggedIn( String username )
323 WebDriverWait wait = new WebDriverWait(getWebDriver(), 10);
324 wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("logout-link")));
325 Assert.assertFalse( isElementVisible( "login-link" ) );
326 Assert.assertFalse( isElementVisible( "register-link" ) );
327 Assert.assertFalse( isElementVisible( "create-admin-link" ) );
330 public void assertCreateAdmin()
332 assertElementPresent( "user-create" );
333 assertFieldValue( "admin", "username" );
334 assertElementPresent( "fullname" );
335 assertElementPresent( "password" );
336 assertElementPresent( "confirmPassword" );
337 assertElementPresent( "email" );
340 public void assertFieldValue( String fieldValue, String fieldName )
342 assertElementPresent( fieldName );
343 Assert.assertEquals( fieldValue, findElement(fieldName ).getAttribute( "value") );
346 public void assertPage( String title )
348 Assert.assertEquals( title, getTitle());
351 public String getTitle()
354 return getWebDriver().getTitle().replaceAll( "[ \n\r]+", " " );
357 public String getHtmlContent()
359 return getWebDriver().getPageSource();
362 public String getText( String locator )
364 return findElement(locator ).getText();
367 public void assertTextPresent( String text )
369 Assert.assertTrue( "'" + text + "' isn't present.", getWebDriver().getPageSource().contains( text ) );
373 public void assertTextNotPresent( String text )
375 Assert.assertFalse( "'" + text + "' is present.", isTextPresent( text ) );
378 public void assertElementPresent( String elementLocator )
380 Assert.assertTrue( "'" + elementLocator + "' isn't present.", isElementPresent( elementLocator ) );
383 public void assertElementNotPresent( String elementLocator )
385 Assert.assertFalse( "'" + elementLocator + "' is present.", isElementPresent( elementLocator ) );
388 public void assertLinkPresent( String text )
390 Assert.assertTrue( "The link '" + text + "' isn't present.", isElementPresent( "//*[text()='" + text+"']//ancestor::a" ) );
393 public void assertLinkNotPresent( String text )
395 Assert.assertFalse( "The link('" + text + "' is present.", isElementPresent( "//*[text()='" + text+"']//ancestor::a" ) );
398 public void assertLinkNotVisible( String text )
400 Assert.assertFalse( "The link('" + text + "' is visible.", isElementVisible( "//*[text()='" + text+"']//ancestor::a" ) );
403 public void assertLinkVisible( String text )
405 Assert.assertTrue( "The link('" + text + "' is not visible.", isElementVisible( "//*[text()='" + text+"']//ancestor::a" ) );
408 public void assertImgWithAlt( String alt )
410 assertElementPresent( "/¯img[@alt='" + alt + "']" );
413 public void assertImgWithAltAtRowCol( boolean isALink, String alt, int row, int column )
415 String locator = "//tr[" + row + "]/td[" + column + "]/";
416 locator += isALink ? "a/" : "";
417 locator += "img[@alt='" + alt + "']";
419 assertElementPresent( locator );
422 public void assertImgWithAltNotPresent( String alt )
424 assertElementNotPresent( "/¯img[@alt='" + alt + "']" );
429 public boolean isTextPresent( String text )
431 return getWebDriver().getPageSource().contains(text);
434 public boolean isLinkPresent( String text )
436 return isElementPresent( "//*[text()='" + text +"']//ancestor::a" );
439 public boolean isElementPresent( String locator )
443 return findElement(locator ) != null;
444 } catch (Exception e) {
449 public boolean isElementVisible(String locator )
452 return findElement(locator).isDisplayed();
453 } catch (Exception e) {
459 public void waitPage()
461 // TODO define a smaller maxWaitTimeJsInMs for wait javascript response for browser side validation
462 //getSelenium().w .wait( Long.parseLong( maxWaitTimeInMs ) );
463 //getSelenium().waitForPageToLoad( maxWaitTimeInMs );
464 // http://jira.openqa.org/browse/SRC-302
465 // those hack looks to break some tests :-(
466 // getSelenium().waitForCondition( "selenium.isElementPresent('document.body');", maxWaitTimeInMs );
467 //getSelenium().waitForCondition( "selenium.isElementPresent('footer');", maxWaitTimeInMs );
468 //getSelenium().waitForCondition( "selenium.browserbot.getCurrentWindow().document.getElementById('footer')",
469 // maxWaitTimeInMs );
470 // so the only hack is to not use a too small wait time
474 Thread.sleep( maxWaitTimeInMs );
476 catch ( InterruptedException e )
478 throw new RuntimeException( "issue on Thread.sleep : " + e.getMessage(), e );
482 public String getFieldValue( String fieldName )
484 return findElement(fieldName ).getAttribute( "value" );
488 public void selectValue( String locator, String value )
490 WebElement element = findElement(locator );
491 Select select = new Select(element);
492 select.selectByValue( value );
495 public WebElement findElement(String locator) {
496 if (locator.startsWith("/")) {
497 return getWebDriver().findElement( By.xpath( locator ) );
499 return getWebDriver().findElement( By.id(locator) );
506 clickLinkWithXPath( "//input[@type='submit']" );
509 public void assertButtonWithValuePresent( String text )
511 Assert.assertTrue( "'" + text + "' button isn't present", isButtonWithValuePresent( text ) );
514 public void assertButtonWithIdPresent( String id )
516 Assert.assertTrue( "'Button with id =" + id + "' isn't present", isButtonWithIdPresent( id ) );
519 public void assertButtonWithValueNotPresent( String text )
521 Assert.assertFalse( "'" + text + "' button is present", isButtonWithValuePresent( text ) );
524 public boolean isButtonWithValuePresent( String text )
526 return isElementPresent( "//button[@value='" + text + "']" ) || isElementPresent(
527 "//input[@value='" + text + "']" );
530 public boolean isButtonWithIdPresent( String text )
532 return isElementPresent( "//button[@id='" + text + "']" ) || isElementPresent( "//input[@id='" + text + "']" );
535 public void clickButtonWithName( String text, boolean wait )
537 clickLinkWithXPath( "//input[@name='" + text + "']", wait );
540 public void clickButtonWithValue( String text )
542 clickButtonWithValue( text, false );
545 public void clickButtonWithValue( String text, boolean wait )
547 assertButtonWithValuePresent( text );
549 if ( isElementPresent( "//button[@value='" + text + "']" ) )
551 clickLinkWithXPath( "//button[@value='" + text + "']", wait );
555 clickLinkWithXPath( "//input[@value='" + text + "']", wait );
559 public void clickSubmitWithLocator( String locator )
561 clickLinkWithLocator( locator );
564 public void clickSubmitWithLocator( String locator, boolean wait )
566 clickLinkWithLocator( locator, wait );
569 public void clickImgWithAlt( String alt )
571 clickLinkWithLocator( "//img[@alt='" + alt + "']" );
574 public void clickLinkWithText( String text )
576 clickLinkWithText( text, false );
579 public void clickLinkWithText( String text, boolean wait )
581 clickLinkWithLocator( "//*[text()='" + text +"']//ancestor::a", wait );
584 public void clickLinkWithXPath( String xpath )
586 clickLinkWithXPath( xpath, false );
589 public void clickLinkWithXPath( String xpath, boolean wait )
591 clickLinkWithLocator( xpath, wait );
594 public void clickLinkWithLocator( String locator )
596 clickLinkWithLocator( locator, false );
599 public void clickLinkWithLocator( String locator, boolean wait )
601 assertElementPresent( locator );
602 findElement(locator).click();
609 public void clickButtonWithLocator( String locator )
611 clickButtonWithLocator( locator, false );
614 public void clickButtonWithLocator( String locator, boolean wait )
616 assertElementPresent( locator );
617 findElement(locator ).click();
624 public <V> V tryClick(By clickableLocator, Function<? super WebDriver, V> conditions, String message, int attempts, int maxWaitTimeInS) {
626 getWebDriver().manage().window().maximize();
627 int count = attempts;
628 WebDriverWait wait = new WebDriverWait( getWebDriver(), maxWaitTimeInS );
631 WebElement el = null;
636 el = wait.until(ExpectedConditions.elementToBeClickable( clickableLocator ));
637 Actions actions = new Actions(getWebDriver());
638 actions.moveToElement(el).click().perform();
639 result = wait.until( conditions );
641 } catch (Exception e) {
642 logger.info("Error: {}, {}, {}",count,e.getClass().getName(), e.getMessage());
644 Point elLoc = el.getLocation();
645 logger.info("Location: x={} y={}", elLoc.getX(), elLoc.getY());
652 Thread.currentThread().sleep(500);
654 catch ( InterruptedException e )
660 Assert.fail( message);
666 * Executes click() on the WebElement <code>el</code> and waits for the conditions.
667 * If the condition is not fulfilled in <code>maxWaitTimeInS</code>, the click is executed again
668 * and waits again for the condition.
669 * After the number of attempts as given by the parameter an assertion error will be thrown, with
670 * the given <code>message</code>.
672 * If the click was successful the element is returned that was created by the condition.
674 * @param el The element where the click is executed
675 * @param conditions The conditions to wait for after the click
676 * @param message The assertion messages
677 * @param attempts Maximum number of click attempts
678 * @param maxWaitTimeInS The time in seconds to wait that the condition is fulfilled.
679 * @param <V> The return type
682 public <V> V tryClick( WebElement el, Function<? super WebDriver, V> conditions, String message, int attempts, int maxWaitTimeInS)
684 int count = attempts;
685 WebDriverWait wait = new WebDriverWait( getWebDriver(), maxWaitTimeInS );
690 if (count<attempts) {
693 result = conditions.apply( getWebDriver() );
695 } catch (Exception e) {
702 result = wait.until( conditions );
704 } catch (Exception e) {
705 logger.info("Error: {}, {}",count, e.getMessage());
711 Thread.currentThread().sleep(500);
713 catch ( InterruptedException e )
719 Assert.fail( message);
724 public <V> V tryClick(WebElement el, Function<? super WebDriver, V> conditions, String message, int attempts )
726 return tryClick( el, conditions, message, attempts, 10 );
729 public <V> V tryClick(WebElement el, Function<? super WebDriver, V> conditions, String message)
731 return tryClick( el, conditions, message, 3);
735 public void setFieldValues( Map<String, String> fieldMap )
737 Map.Entry<String, String> entry;
739 for ( Iterator<Entry<String, String>> entries = fieldMap.entrySet().iterator(); entries.hasNext(); )
741 entry = entries.next();
743 setFieldValue( entry.getKey(), entry.getValue() );
747 public void setFieldValue( String fieldName, String value )
749 findElement(fieldName ).sendKeys( value );
752 public void checkField( String locator )
754 WebElement element = findElement(locator );
755 if (!element.isSelected()) {
760 public void uncheckField( String locator )
762 WebElement element = findElement(locator );
763 if (element.isSelected()) {
768 public boolean isChecked( String locator )
770 return findElement(locator ).isSelected();
773 public void assertIsChecked( String locator )
776 Assert.assertTrue( isChecked( locator ));
779 public void assertIsNotChecked( String locator )
782 Assert.assertFalse( isChecked( locator ) );
787 public String captureScreenShotOnFailure( Throwable failure, String methodName, String className )
789 SimpleDateFormat sdf = new SimpleDateFormat( "yyyy.MM.dd-HH_mm_ss" );
790 String time = sdf.format( new Date() );
791 File targetPath = new File( "target", "screenshots" );
795 for ( StackTraceElement stackTrace : failure.getStackTrace() )
797 if ( stackTrace.getClassName().equals( this.getClass().getName() ) )
799 lineNumber = stackTrace.getLineNumber();
805 if (getWebDriver()!=null)
807 String fileBaseName = methodName + "_" + className + ".java_" + lineNumber + "-" + time;
808 File fileName = new File( targetPath, fileBaseName + ".png" );
809 Path screenshot = WebdriverUtility.takeScreenShot( fileName.getName(), getWebDriver());
810 return fileName.getAbsolutePath();