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 wait = new WebDriverWait( getWebDriver(), 20 );
144 Boolean found = wait.until( ExpectedConditions.or(
145 ExpectedConditions.visibilityOfElementLocated(By.id("create-admin-link-a")),
146 ExpectedConditions.visibilityOfElementLocated(By.id("login-link-a"))));
150 WebElement adminLink = getWebDriver().findElement( By.id( "create-admin-link-a" ) );
151 WebElement loginLink = getWebDriver().findElement( By.id( "login-link-a" ) );
153 // if not admin user created create one
154 if ( adminLink != null && adminLink.isDisplayed() )
157 Assert.assertFalse( isElementVisible( "login-link-a" ) );
158 Assert.assertFalse( isElementVisible( "register-link-a" ) );
159 // skygo need to set to true for passing is that work as expected ?
161 wait = new WebDriverWait( getWebDriver(), 10 );
162 wait.until( ExpectedConditions.visibilityOfElementLocated( By.id( "user-create" ) ) );
164 String fullname = getProperty( "ADMIN_FULLNAME" );
165 String username = getAdminUsername();
166 String mail = getProperty( "ADMIN_EMAIL" );
167 String password = getProperty( "ADMIN_PASSWORD" );
168 submitAdminData( fullname, mail, password );
169 assertUserLoggedIn( username );
170 clickLinkWithLocator( "logout-link-a", false );
172 else if ( loginLink != null && loginLink.isDisplayed() )
174 Assert.assertTrue( isElementVisible( "login-link-a" ) );
175 Assert.assertTrue( isElementVisible( "register-link-a" ) );
176 login( getAdminUsername(), getAdminPassword() );
182 public WebDriver getWebDriver() {
183 return this.webDriver;
186 protected String getProperty( String key )
188 return p.getProperty( key );
191 public String getAdminUsername()
193 String adminUsername = getProperty( "ADMIN_USERNAME" );
194 return adminUsername;
197 public String getAdminPassword()
199 String adminPassword = getProperty( "ADMIN_PASSWORD" );
200 return adminPassword;
203 public void submitAdminData( String fullname, String email, String password )
205 setFieldValue( "fullname", fullname );
206 setFieldValue( "email", email );
207 setFieldValue( "password", password );
208 setFieldValue( "confirmPassword", password );
209 clickButtonWithLocator( "user-create-form-register-button" , false);
212 public void login( String username, String password )
214 login( username, password, true, "Login Page" );
217 public void login( String username, String password, boolean valid, String assertReturnPage )
219 if ( isElementVisible( "login-link-a" ) )//isElementPresent( "loginLink" ) )
223 submitLoginPage( username, password, false, valid, assertReturnPage );
227 assertUserLoggedIn( username );
232 public void goToLoginPage()
234 logger.info("Goto login page");
235 getWebDriver().get( baseUrl );
236 WebDriverWait wait = new WebDriverWait(getWebDriver(),30);
237 wait.until(ExpectedConditions.presenceOfElementLocated(By.id("topbar-menu")));
238 wait.until(ExpectedConditions.or(ExpectedConditions.visibilityOfElementLocated(By.id("logout-link")),
239 ExpectedConditions.visibilityOfElementLocated(By.id("login-link-a"))));
241 // are we already logged in ?
242 if ( isElementVisible( "logout-link" ) ) //isElementPresent( "logoutLink" ) )
244 logger.info("Logging out ");
246 clickLinkWithLocator( "logout-link-a", false );
248 wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("login-link-a")));
249 clickLinkWithLocator( "login-link-a", false );
250 // This is a workaround for bug with HTMLUnit. The display attribute of the
251 // login dialog is not changed via the click.
252 // TODO: Check after changing jquery, bootstrap or htmlunit version
253 if (getWebDriver() instanceof HtmlUnitDriver)
255 ( (JavascriptExecutor) getWebDriver() ).executeScript( "$('#modal-login').show();" );
258 wait = new WebDriverWait(getWebDriver(),20);
259 wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("modal-login")));
264 public void assertLoginModal()
266 assertElementPresent( "user-login-form" );
267 Assert.assertTrue( isElementVisible( "register-link" ) );
268 Assert.assertTrue( isElementVisible("user-login-form-username" ));
269 Assert.assertTrue( isElementVisible("user-login-form-password" ));
270 assertButtonWithIdPresent( "modal-login-ok" );
271 Assert.assertTrue( isElementVisible( "modal-login-ok" ));
275 public void submitLoginPage( String username, String password )
277 submitLoginPage( username, password, false, true, "Login Page" );
280 public void submitLoginPage( String username, String password, boolean validUsernamePassword )
282 submitLoginPage( username, password, false, validUsernamePassword, "Login Page" );
285 public void submitLoginPage( String username, String password, boolean rememberMe, boolean validUsernamePassword,
286 String assertReturnPage )
288 logger.info("Activating login form");
289 // clickLinkWithLocator( "login-link-a", false);
290 WebDriverWait wait = new WebDriverWait(getWebDriver(),5);
291 WebElement usernameField = wait.until(ExpectedConditions.visibilityOf(getWebDriver().findElement(By.id("user-login-form-username"))));
292 wait = new WebDriverWait(getWebDriver(),5);
293 WebElement passwordField = wait.until(ExpectedConditions.visibilityOf(getWebDriver().findElement(By.id("user-login-form-password"))));
294 wait = new WebDriverWait(getWebDriver(),5);
295 WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.id("modal-login-ok")));
296 usernameField.sendKeys(username);
297 passwordField.sendKeys(password);
301 checkField( "rememberMe" );
305 if ( validUsernamePassword )
307 assertUserLoggedIn( username );
312 if ( "Login Page".equals( assertReturnPage ) )
318 assertPage( assertReturnPage );
323 // *******************************************************
324 // Auxiliar methods. This method help us and simplify test.
325 // *******************************************************
327 protected void assertUserLoggedIn( String username )
329 WebDriverWait wait = new WebDriverWait(getWebDriver(), 10);
330 wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("logout-link")));
331 Assert.assertFalse( isElementVisible( "login-link" ) );
332 Assert.assertFalse( isElementVisible( "register-link" ) );
333 Assert.assertFalse( isElementVisible( "create-admin-link" ) );
336 public void assertCreateAdmin()
338 assertElementPresent( "user-create" );
339 assertFieldValue( "admin", "username" );
340 assertElementPresent( "fullname" );
341 assertElementPresent( "password" );
342 assertElementPresent( "confirmPassword" );
343 assertElementPresent( "email" );
346 public void assertFieldValue( String fieldValue, String fieldName )
348 assertElementPresent( fieldName );
349 Assert.assertEquals( fieldValue, findElement(fieldName ).getAttribute( "value") );
352 public void assertPage( String title )
354 Assert.assertEquals( title, getTitle());
357 public String getTitle()
360 return getWebDriver().getTitle().replaceAll( "[ \n\r]+", " " );
363 public String getHtmlContent()
365 return getWebDriver().getPageSource();
368 public String getText( String locator )
370 return findElement(locator ).getText();
373 public void assertTextPresent( String text )
375 Assert.assertTrue( "'" + text + "' isn't present.", getWebDriver().getPageSource().contains( text ) );
379 public void assertTextNotPresent( String text )
381 Assert.assertFalse( "'" + text + "' is present.", isTextPresent( text ) );
384 public void assertElementPresent( String elementLocator )
386 Assert.assertTrue( "'" + elementLocator + "' isn't present.", isElementPresent( elementLocator ) );
389 public void assertElementNotPresent( String elementLocator )
391 Assert.assertFalse( "'" + elementLocator + "' is present.", isElementPresent( elementLocator ) );
394 public void assertLinkPresent( String text )
396 Assert.assertTrue( "The link '" + text + "' isn't present.", isElementPresent( "//*[text()='" + text+"']//ancestor::a" ) );
399 public void assertLinkNotPresent( String text )
401 Assert.assertFalse( "The link('" + text + "' is present.", isElementPresent( "//*[text()='" + text+"']//ancestor::a" ) );
404 public void assertLinkNotVisible( String text )
406 Assert.assertFalse( "The link('" + text + "' is visible.", isElementVisible( "//*[text()='" + text+"']//ancestor::a" ) );
409 public void assertLinkVisible( String text )
411 Assert.assertTrue( "The link('" + text + "' is not visible.", isElementVisible( "//*[text()='" + text+"']//ancestor::a" ) );
414 public void assertImgWithAlt( String alt )
416 assertElementPresent( "/¯img[@alt='" + alt + "']" );
419 public void assertImgWithAltAtRowCol( boolean isALink, String alt, int row, int column )
421 String locator = "//tr[" + row + "]/td[" + column + "]/";
422 locator += isALink ? "a/" : "";
423 locator += "img[@alt='" + alt + "']";
425 assertElementPresent( locator );
428 public void assertImgWithAltNotPresent( String alt )
430 assertElementNotPresent( "/¯img[@alt='" + alt + "']" );
435 public boolean isTextPresent( String text )
437 return getWebDriver().getPageSource().contains(text);
440 public boolean isLinkPresent( String text )
442 return isElementPresent( "//*[text()='" + text +"']//ancestor::a" );
445 public boolean isElementPresent( String locator )
449 return findElement(locator ) != null;
450 } catch (Exception e) {
455 public boolean isElementVisible(String locator )
458 return findElement(locator).isDisplayed();
459 } catch (Exception e) {
465 public void waitPage()
467 // TODO define a smaller maxWaitTimeJsInMs for wait javascript response for browser side validation
468 //getSelenium().w .wait( Long.parseLong( maxWaitTimeInMs ) );
469 //getSelenium().waitForPageToLoad( maxWaitTimeInMs );
470 // http://jira.openqa.org/browse/SRC-302
471 // those hack looks to break some tests :-(
472 // getSelenium().waitForCondition( "selenium.isElementPresent('document.body');", maxWaitTimeInMs );
473 //getSelenium().waitForCondition( "selenium.isElementPresent('footer');", maxWaitTimeInMs );
474 //getSelenium().waitForCondition( "selenium.browserbot.getCurrentWindow().document.getElementById('footer')",
475 // maxWaitTimeInMs );
476 // so the only hack is to not use a too small wait time
480 Thread.sleep( maxWaitTimeInMs );
482 catch ( InterruptedException e )
484 throw new RuntimeException( "issue on Thread.sleep : " + e.getMessage(), e );
488 public String getFieldValue( String fieldName )
490 return findElement(fieldName ).getAttribute( "value" );
494 public void selectValue( String locator, String value )
496 WebElement element = findElement(locator );
497 Select select = new Select(element);
498 select.selectByValue( value );
501 public WebElement findElement(String locator) {
502 if (locator.startsWith("/")) {
503 return getWebDriver().findElement( By.xpath( locator ) );
505 return getWebDriver().findElement( By.id(locator) );
512 clickLinkWithXPath( "//input[@type='submit']" );
515 public void assertButtonWithValuePresent( String text )
517 Assert.assertTrue( "'" + text + "' button isn't present", isButtonWithValuePresent( text ) );
520 public void assertButtonWithIdPresent( String id )
522 Assert.assertTrue( "'Button with id =" + id + "' isn't present", isButtonWithIdPresent( id ) );
525 public void assertButtonWithValueNotPresent( String text )
527 Assert.assertFalse( "'" + text + "' button is present", isButtonWithValuePresent( text ) );
530 public boolean isButtonWithValuePresent( String text )
532 return isElementPresent( "//button[@value='" + text + "']" ) || isElementPresent(
533 "//input[@value='" + text + "']" );
536 public boolean isButtonWithIdPresent( String text )
538 return isElementPresent( "//button[@id='" + text + "']" ) || isElementPresent( "//input[@id='" + text + "']" );
541 public void clickButtonWithName( String text, boolean wait )
543 clickLinkWithXPath( "//input[@name='" + text + "']", wait );
546 public void clickButtonWithValue( String text )
548 clickButtonWithValue( text, false );
551 public void clickButtonWithValue( String text, boolean wait )
553 assertButtonWithValuePresent( text );
555 if ( isElementPresent( "//button[@value='" + text + "']" ) )
557 clickLinkWithXPath( "//button[@value='" + text + "']", wait );
561 clickLinkWithXPath( "//input[@value='" + text + "']", wait );
565 public void clickSubmitWithLocator( String locator )
567 clickLinkWithLocator( locator );
570 public void clickSubmitWithLocator( String locator, boolean wait )
572 clickLinkWithLocator( locator, wait );
575 public void clickImgWithAlt( String alt )
577 clickLinkWithLocator( "//img[@alt='" + alt + "']" );
580 public void clickLinkWithText( String text )
582 clickLinkWithText( text, false );
585 public void clickLinkWithText( String text, boolean wait )
587 clickLinkWithLocator( "//*[text()='" + text +"']//ancestor::a", wait );
590 public void clickLinkWithXPath( String xpath )
592 clickLinkWithXPath( xpath, false );
595 public void clickLinkWithXPath( String xpath, boolean wait )
597 clickLinkWithLocator( xpath, wait );
600 public void clickLinkWithLocator( String locator )
602 clickLinkWithLocator( locator, false );
605 public void clickLinkWithLocator( String locator, boolean wait )
607 assertElementPresent( locator );
608 findElement(locator).click();
615 public void clickButtonWithLocator( String locator )
617 clickButtonWithLocator( locator, false );
620 public void clickButtonWithLocator( String locator, boolean wait )
622 assertElementPresent( locator );
623 findElement(locator ).click();
630 public <V> V tryClick(By clickableLocator, Function<? super WebDriver, V> conditions, String message, int attempts, int maxWaitTimeInS) {
632 getWebDriver().manage().window().maximize();
633 int count = attempts;
634 WebDriverWait wait = new WebDriverWait( getWebDriver(), maxWaitTimeInS );
637 WebElement el = null;
642 el = wait.until(ExpectedConditions.elementToBeClickable( clickableLocator ));
643 Actions actions = new Actions(getWebDriver());
644 actions.moveToElement(el).click().perform();
645 result = wait.until( conditions );
647 } catch (Exception e) {
648 logger.info("Error: {}, {}, {}",count,e.getClass().getName(), e.getMessage());
650 Point elLoc = el.getLocation();
651 logger.info("Location: x={} y={}", elLoc.getX(), elLoc.getY());
658 Thread.currentThread().sleep(500);
660 catch ( InterruptedException e )
666 Assert.fail( message);
672 * Executes click() on the WebElement <code>el</code> and waits for the conditions.
673 * If the condition is not fulfilled in <code>maxWaitTimeInS</code>, the click is executed again
674 * and waits again for the condition.
675 * After the number of attempts as given by the parameter an assertion error will be thrown, with
676 * the given <code>message</code>.
678 * If the click was successful the element is returned that was created by the condition.
680 * @param el The element where the click is executed
681 * @param conditions The conditions to wait for after the click
682 * @param message The assertion messages
683 * @param attempts Maximum number of click attempts
684 * @param maxWaitTimeInS The time in seconds to wait that the condition is fulfilled.
685 * @param <V> The return type
688 public <V> V tryClick( WebElement el, Function<? super WebDriver, V> conditions, String message, int attempts, int maxWaitTimeInS)
690 int count = attempts;
691 WebDriverWait wait = new WebDriverWait( getWebDriver(), maxWaitTimeInS );
696 if (count<attempts) {
699 result = conditions.apply( getWebDriver() );
701 } catch (Exception e) {
708 result = wait.until( conditions );
710 } catch (Exception e) {
711 logger.info("Error: {}, {}",count, e.getMessage());
717 Thread.currentThread().sleep(500);
719 catch ( InterruptedException e )
725 Assert.fail( message);
730 public <V> V tryClick(WebElement el, Function<? super WebDriver, V> conditions, String message, int attempts )
732 return tryClick( el, conditions, message, attempts, 10 );
735 public <V> V tryClick(WebElement el, Function<? super WebDriver, V> conditions, String message)
737 return tryClick( el, conditions, message, 3);
741 public void setFieldValues( Map<String, String> fieldMap )
743 Map.Entry<String, String> entry;
745 for ( Iterator<Entry<String, String>> entries = fieldMap.entrySet().iterator(); entries.hasNext(); )
747 entry = entries.next();
749 setFieldValue( entry.getKey(), entry.getValue() );
753 public void setFieldValue( String fieldName, String value )
755 findElement(fieldName ).sendKeys( value );
758 public void checkField( String locator )
760 WebElement element = findElement(locator );
761 if (!element.isSelected()) {
766 public void uncheckField( String locator )
768 WebElement element = findElement(locator );
769 if (element.isSelected()) {
774 public boolean isChecked( String locator )
776 return findElement(locator ).isSelected();
779 public void assertIsChecked( String locator )
782 Assert.assertTrue( isChecked( locator ));
785 public void assertIsNotChecked( String locator )
788 Assert.assertFalse( isChecked( locator ) );
793 public String captureScreenShotOnFailure( Throwable failure, String methodName, String className )
795 SimpleDateFormat sdf = new SimpleDateFormat( "yyyy.MM.dd-HH_mm_ss" );
796 String time = sdf.format( new Date() );
797 File targetPath = new File( "target", "screenshots" );
801 for ( StackTraceElement stackTrace : failure.getStackTrace() )
803 if ( stackTrace.getClassName().equals( this.getClass().getName() ) )
805 lineNumber = stackTrace.getLineNumber();
811 if (getWebDriver()!=null)
813 String fileBaseName = methodName + "_" + className + ".java_" + lineNumber + "-" + time;
814 File fileName = new File( targetPath, fileBaseName + ".png" );
815 Path screenshot = WebdriverUtility.takeScreenShot( fileName.getName(), getWebDriver());
816 return fileName.getAbsolutePath();