]> source.dussan.org Git - archiva.git/blob
f7d9799737dec31622cd0ce99ec095bcad31407f
[archiva.git] /
1 package org.apache.archiva.web.test.parent;
2
3 /*
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
11  *
12  *   http://www.apache.org/licenses/LICENSE-2.0
13  *
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
19  * under the License.
20  */
21
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;
26 import org.openqa.selenium.*;
27 import org.openqa.selenium.htmlunit.HtmlUnitDriver;
28 import org.openqa.selenium.interactions.Actions;
29 import org.openqa.selenium.support.ui.ExpectedConditions;
30 import org.openqa.selenium.support.ui.Select;
31 import org.openqa.selenium.support.ui.WebDriverWait;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 import java.io.IOException;
36 import java.nio.file.Files;
37 import java.nio.file.Path;
38 import java.nio.file.Paths;
39 import java.text.SimpleDateFormat;
40 import java.util.ArrayList;
41 import java.util.Date;
42 import java.util.Iterator;
43 import java.util.List;
44 import java.util.Map;
45 import java.util.Map.Entry;
46 import java.util.Properties;
47 import java.util.function.Function;
48
49 /**
50  * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
51  *
52  */
53
54 public abstract class AbstractSeleniumTest
55 {
56     private final Logger logger = LoggerFactory.getLogger( getClass() );
57
58     @Rule
59     public ArchivaSeleniumExecutionRule archivaSeleniumExecutionRule = new ArchivaSeleniumExecutionRule();
60
61     public String browser = System.getProperty( "browser" );
62
63     public String baseUrl =
64         "http://localhost:" + System.getProperty( "container.http.port" ) + "/archiva/index.html?request_lang=en";
65
66     public int maxWaitTimeInMs = Integer.getInteger( "maxWaitTimeInMs" );
67
68     public String seleniumHost = System.getProperty( "seleniumHost", "localhost" );
69
70     public int seleniumPort = Integer.getInteger( "seleniumPort", 4444 );
71
72     public boolean remoteSelenium = Boolean.parseBoolean( System.getProperty( "seleniumRemote", "false" ) );
73
74     WebDriver webDriver = null;
75
76     public Properties p;
77
78     /**
79      * this method is called by the Rule before executing a test
80      *
81      * @throws Exception
82      */
83     public void open()
84         throws Exception
85     {
86         p = new Properties();
87         p.load( this.getClass().getClassLoader().getResourceAsStream( "test.properties" ) );
88
89         baseUrl = WebdriverUtility.getBaseUrl()+"/index.html?request_lang=en";
90
91         open( baseUrl, browser, seleniumHost, seleniumPort, maxWaitTimeInMs, remoteSelenium );
92         assertAdminCreated();
93     }
94
95     /**
96      * this method is called by the Rule after executing a tests
97      */
98     public void close()
99     {
100         getWebDriver().close();
101     }
102
103     /**
104      * Initialize selenium
105      */
106     public void open( String baseUrl, String browser, String seleniumHost, int seleniumPort, int maxWaitTimeInMs, boolean remoteSelenium)
107         throws Exception
108     {
109         try
110         {
111             if ( getWebDriver() == null )
112             {
113                 WebDriver driver = WebdriverUtility.newWebDriver(browser, seleniumHost, seleniumPort, remoteSelenium);
114                 // selenium.start();
115                 // selenium.setTimeout( Integer.toString( maxWaitTimeInMs ) );
116                 this.webDriver = driver;
117             }
118         }
119         catch ( Exception e )
120         {
121             // yes
122             System.out.print( e.getMessage() );
123             e.printStackTrace();
124         }
125     }
126
127     public void assertAdminCreated()
128         throws Exception
129     {
130         initializeArchiva( baseUrl, browser, maxWaitTimeInMs, seleniumHost, seleniumPort, remoteSelenium );
131     }
132
133     public void loadPage(String url, int timeout) {
134         getWebDriver().get( url );
135         WebDriverWait wait = new WebDriverWait( getWebDriver(), timeout );
136         wait.until( new Function<WebDriver, Boolean>()
137                     {
138                         public Boolean apply( WebDriver driver )
139                         {
140                             return ( (JavascriptExecutor) driver ).executeScript( "return document.readyState" ).equals( "complete" );
141                         }
142                     }
143         );
144     }
145
146     public void initializeArchiva( String baseUrl, String browser, int maxWaitTimeInMs, String seleniumHost,
147                                    int seleniumPort, boolean remoteSelenium)
148         throws Exception
149     {
150
151         open( baseUrl, browser, seleniumHost, seleniumPort, maxWaitTimeInMs, remoteSelenium);
152
153         loadPage(baseUrl, 30);
154         WebDriverWait wait = new WebDriverWait(getWebDriver(),30);
155         wait.until(ExpectedConditions.presenceOfElementLocated(By.id("topbar-menu")));
156
157         wait = new WebDriverWait( getWebDriver(), 20 );
158         Boolean found = wait.until( ExpectedConditions.or(
159                     ExpectedConditions.visibilityOfElementLocated(By.id("create-admin-link-a")),
160                             ExpectedConditions.visibilityOfElementLocated(By.id("login-link-a"))));
161         if (found)
162         {
163
164             WebElement adminLink = getWebDriver().findElement( By.id( "create-admin-link-a" ) );
165             WebElement loginLink = getWebDriver().findElement( By.id( "login-link-a" ) );
166
167             // if not admin user created create one
168             if ( adminLink != null && adminLink.isDisplayed() )
169             {
170
171                 Assert.assertFalse( isElementVisible( "login-link-a" ) );
172                 Assert.assertFalse( isElementVisible( "register-link-a" ) );
173                 // skygo need to set to true for passing is that work as expected ?
174                 adminLink.click();
175                 wait = new WebDriverWait( getWebDriver(), 10 );
176                 wait.until( ExpectedConditions.visibilityOfElementLocated( By.id( "user-create" ) ) );
177                 assertCreateAdmin();
178                 String fullname = getProperty( "ADMIN_FULLNAME" );
179                 String username = getAdminUsername();
180                 String mail = getProperty( "ADMIN_EMAIL" );
181                 String password = getProperty( "ADMIN_PASSWORD" );
182                 submitAdminData( fullname, mail, password );
183                 assertUserLoggedIn( username );
184                 clickLinkWithLocator( "logout-link-a", false );
185             }
186                  else if ( loginLink != null && loginLink.isDisplayed() )
187             {
188                 Assert.assertTrue( isElementVisible( "login-link-a" ) );
189                 Assert.assertTrue( isElementVisible( "register-link-a" ) );
190                 login( getAdminUsername(), getAdminPassword() );
191             }
192         }
193
194     }
195
196     public WebDriver getWebDriver() {
197         return this.webDriver;
198     }
199
200     protected String getProperty( String key )
201     {
202         return p.getProperty( key );
203     }
204
205     public String getAdminUsername()
206     {
207         String adminUsername = getProperty( "ADMIN_USERNAME" );
208         return adminUsername;
209     }
210
211     public String getAdminPassword()
212     {
213         String adminPassword = getProperty( "ADMIN_PASSWORD" );
214         return adminPassword;
215     }
216
217     public void submitAdminData( String fullname, String email, String password )
218     {
219         setFieldValue( "fullname", fullname );
220         setFieldValue( "email", email );
221         setFieldValue( "password", password );
222         setFieldValue( "confirmPassword", password );
223         clickButtonWithLocator( "user-create-form-register-button" , false);
224     }
225
226     public void login( String username, String password )
227     {
228         login( username, password, true, "Login Page" );
229     }
230
231     public void login( String username, String password, boolean valid, String assertReturnPage )
232     {
233         if ( isElementVisible( "login-link-a" ) )//isElementPresent( "loginLink" ) )
234         {
235             goToLoginPage();
236
237             submitLoginPage( username, password, false, valid, assertReturnPage );
238         }
239         if ( valid )
240         {
241             assertUserLoggedIn( username );
242         }
243     }
244
245     // Go to Login Page
246     public void goToLoginPage()
247     {
248         logger.info("Goto login page");
249         loadPage(baseUrl, 30);
250         WebDriverWait wait = new WebDriverWait(getWebDriver(),30);
251         wait.until(ExpectedConditions.presenceOfElementLocated(By.id("topbar-menu")));
252         wait.until(ExpectedConditions.or(ExpectedConditions.visibilityOfElementLocated(By.id("logout-link")),
253                 ExpectedConditions.visibilityOfElementLocated(By.id("login-link-a"))));
254
255         // are we already logged in ?
256         if ( isElementVisible( "logout-link" ) ) //isElementPresent( "logoutLink" ) )
257         {
258             logger.info("Logging out ");
259             // so logout
260             clickLinkWithLocator( "logout-link-a", false );
261         }
262         wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("login-link-a")));
263         clickLinkWithLocator( "login-link-a", false );
264         // This is a workaround for bug with HTMLUnit. The display attribute of the
265         // login dialog is not changed via the click.
266         // TODO: Check after changing jquery, bootstrap or htmlunit version
267         if (getWebDriver() instanceof HtmlUnitDriver)
268         {
269             ( (JavascriptExecutor) getWebDriver() ).executeScript( "$('#modal-login').show();" );
270         }
271         // END OF WORKAROUND
272         wait = new WebDriverWait(getWebDriver(),20);
273         wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("modal-login")));
274         assertLoginModal();
275     }
276
277
278     public void assertLoginModal()
279     {
280         assertElementPresent( "user-login-form" );
281         Assert.assertTrue( isElementVisible( "register-link" ) );
282         Assert.assertTrue( isElementVisible("user-login-form-username" ));
283         Assert.assertTrue( isElementVisible("user-login-form-password" ));
284         assertButtonWithIdPresent( "modal-login-ok" );
285         Assert.assertTrue( isElementVisible( "modal-login-ok" ));
286     }
287
288
289     public void submitLoginPage( String username, String password )
290     {
291         submitLoginPage( username, password, false, true, "Login Page" );
292     }
293
294     public void submitLoginPage( String username, String password, boolean validUsernamePassword )
295     {
296         submitLoginPage( username, password, false, validUsernamePassword, "Login Page" );
297     }
298
299     public void submitLoginPage( String username, String password, boolean rememberMe, boolean validUsernamePassword,
300                                  String assertReturnPage )
301     {
302         logger.info("Activating login form");
303         // clickLinkWithLocator( "login-link-a", false);
304         WebDriverWait wait = new WebDriverWait(getWebDriver(),5);
305         WebElement usernameField = wait.until(ExpectedConditions.visibilityOf(getWebDriver().findElement(By.id("user-login-form-username"))));
306         wait = new WebDriverWait(getWebDriver(),5);
307         WebElement passwordField = wait.until(ExpectedConditions.visibilityOf(getWebDriver().findElement(By.id("user-login-form-password"))));
308         wait = new WebDriverWait(getWebDriver(),5);
309         WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.id("modal-login-ok")));
310         usernameField.sendKeys(username);
311         passwordField.sendKeys(password);
312         /*
313         if ( rememberMe )
314         {
315             checkField( "rememberMe" );
316         }*/
317
318         button.click();
319         if ( validUsernamePassword )
320         {
321             assertUserLoggedIn( username );
322         }
323         /*
324         else
325         {
326             if ( "Login Page".equals( assertReturnPage ) )
327             {
328                 assertLoginPage();
329             }
330             else
331             {
332                 assertPage( assertReturnPage );
333             }
334         }*/
335     }
336
337     // *******************************************************
338     // Auxiliar methods. This method help us and simplify test.
339     // *******************************************************
340
341     protected void assertUserLoggedIn( String username )
342     {
343         WebDriverWait wait = new WebDriverWait(getWebDriver(), 10);
344         wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("logout-link")));
345         Assert.assertFalse( isElementVisible( "login-link" ) );
346         Assert.assertFalse( isElementVisible( "register-link" ) );
347         Assert.assertFalse( isElementVisible( "create-admin-link" ) );
348     }
349
350     public void assertCreateAdmin()
351     {
352         assertElementPresent( "user-create" );
353         assertFieldValue( "admin", "username" );
354         assertElementPresent( "fullname" );
355         assertElementPresent( "password" );
356         assertElementPresent( "confirmPassword" );
357         assertElementPresent( "email" );
358     }
359
360     public void assertFieldValue( String fieldValue, String fieldName )
361     {
362         assertElementPresent( fieldName );
363         Assert.assertEquals( fieldValue, findElement(fieldName ).getAttribute( "value") );
364     }
365
366     public void assertPage( String title )
367     {
368         Assert.assertEquals( title,  getTitle());
369     }
370
371     public String getTitle()
372     {
373         // Collapse spaces
374         return getWebDriver().getTitle().replaceAll( "[ \n\r]+", " " );
375     }
376
377     public String getHtmlContent()
378     {
379         return getWebDriver().getPageSource();
380     }
381
382     public String getText( String locator )
383     {
384         return findElement(locator ).getText();
385     }
386
387     public void assertTextPresent( String text )
388     {
389         Assert.assertTrue( "'" + text + "' isn't present.", getWebDriver().getPageSource().contains( text ) );
390     }
391
392
393     public void assertTextNotPresent( String text )
394     {
395         Assert.assertFalse( "'" + text + "' is present.", isTextPresent( text ) );
396     }
397
398     public void assertElementPresent( String elementLocator )
399     {
400         Assert.assertTrue( "'" + elementLocator + "' isn't present.", isElementPresent( elementLocator ) );
401     }
402
403     public void assertElementNotPresent( String elementLocator )
404     {
405         Assert.assertFalse( "'" + elementLocator + "' is present.", isElementPresent( elementLocator ) );
406     }
407
408     public void assertLinkPresent( String text )
409     {
410         Assert.assertTrue( "The link '" + text + "' isn't present.", isElementPresent( "//*[text()='" + text+"']//ancestor::a"  ) );
411     }
412
413     public void assertLinkNotPresent( String text )
414     {
415         Assert.assertFalse( "The link('" + text + "' is present.", isElementPresent( "//*[text()='" + text+"']//ancestor::a" ) );
416     }
417
418     public void assertLinkNotVisible( String text )
419     {
420         Assert.assertFalse( "The link('" + text + "' is visible.", isElementVisible( "//*[text()='" + text+"']//ancestor::a"  ) );
421     }
422
423     public void assertLinkVisible( String text )
424     {
425         Assert.assertTrue( "The link('" + text + "' is not visible.", isElementVisible( "//*[text()='" + text+"']//ancestor::a" ) );
426     }
427
428     public void assertImgWithAlt( String alt )
429     {
430         assertElementPresent( "/¯img[@alt='" + alt + "']" );
431     }
432
433     public void assertImgWithAltAtRowCol( boolean isALink, String alt, int row, int column )
434     {
435         String locator = "//tr[" + row + "]/td[" + column + "]/";
436         locator += isALink ? "a/" : "";
437         locator += "img[@alt='" + alt + "']";
438
439         assertElementPresent( locator );
440     }
441
442     public void assertImgWithAltNotPresent( String alt )
443     {
444         assertElementNotPresent( "/¯img[@alt='" + alt + "']" );
445     }
446
447
448
449     public boolean isTextPresent( String text )
450     {
451         return getWebDriver().getPageSource().contains(text);
452     }
453
454     public boolean isLinkPresent( String text )
455     {
456         return isElementPresent( "//*[text()='" + text +"']//ancestor::a" );
457     }
458
459     public boolean isElementPresent( String locator )
460     {
461         try
462         {
463             return findElement(locator ) != null;
464         } catch (Exception e) {
465             return false;
466         }
467     }
468
469     public boolean isElementVisible(String locator )
470     {
471         try {
472             return findElement(locator).isDisplayed();
473         } catch (Exception e) {
474             return false;
475         }
476     }
477
478
479     public void waitPage()
480     {
481         // TODO define a smaller maxWaitTimeJsInMs for wait javascript response for browser side validation
482         //getSelenium().w .wait( Long.parseLong( maxWaitTimeInMs ) );
483         //getSelenium().waitForPageToLoad( maxWaitTimeInMs );
484         // http://jira.openqa.org/browse/SRC-302
485         // those hack looks to break some tests :-(
486         // getSelenium().waitForCondition( "selenium.isElementPresent('document.body');", maxWaitTimeInMs );
487         //getSelenium().waitForCondition( "selenium.isElementPresent('footer');", maxWaitTimeInMs );
488         //getSelenium().waitForCondition( "selenium.browserbot.getCurrentWindow().document.getElementById('footer')",
489         //                                maxWaitTimeInMs );
490         // so the only hack is to not use a too small wait time
491
492         try
493         {
494             Thread.sleep( maxWaitTimeInMs );
495         }
496         catch ( InterruptedException e )
497         {
498             throw new RuntimeException( "issue on Thread.sleep : " + e.getMessage(), e );
499         }
500     }
501
502     public String getFieldValue( String fieldName )
503     {
504         return findElement(fieldName ).getAttribute( "value" );
505     }
506
507
508     public WebElement selectValue( String locator, String value) {
509         return this.selectValue( locator, value, false );
510     }
511
512     public WebElement selectValue( String locator, String value, boolean scrollToView )
513     {
514         int count = 5;
515         boolean check = true;
516         WebDriverWait wait = new WebDriverWait( getWebDriver( ), 10 );
517         WebElement element = null;
518         while(check && count-->0)
519         {
520             try
521             {
522                 element = findElement( locator );
523                 List<WebElement> elementList = new ArrayList<>( );
524                 elementList.add( element );
525                 wait.until( ExpectedConditions.visibilityOfAllElements( elementList ) );
526                 check=false;
527             } catch (Throwable e) {
528                 logger.info("Waiting for select element {} to be visible", locator);
529             }
530         }
531         Select select = new Select(element);
532         select.selectByValue( value );
533         return element;
534     }
535
536     public WebElement findElement(String locator) {
537         if (locator.startsWith("/")) {
538             return getWebDriver().findElement( By.xpath( locator ) );
539         } else {
540             return getWebDriver().findElement( By.id(locator) );
541         }
542     }
543
544
545     public void submit()
546     {
547         clickLinkWithXPath( "//input[@type='submit']" );
548     }
549
550     public void assertButtonWithValuePresent( String text )
551     {
552         Assert.assertTrue( "'" + text + "' button isn't present", isButtonWithValuePresent( text ) );
553     }
554
555     public void assertButtonWithIdPresent( String id )
556     {
557         Assert.assertTrue( "'Button with id =" + id + "' isn't present", isButtonWithIdPresent( id ) );
558     }
559
560     public void assertButtonWithValueNotPresent( String text )
561     {
562         Assert.assertFalse( "'" + text + "' button is present", isButtonWithValuePresent( text ) );
563     }
564
565     public boolean isButtonWithValuePresent( String text )
566     {
567         return isElementPresent( "//button[@value='" + text + "']" ) || isElementPresent(
568             "//input[@value='" + text + "']" );
569     }
570
571     public boolean isButtonWithIdPresent( String text )
572     {
573         return isElementPresent( "//button[@id='" + text + "']" ) || isElementPresent( "//input[@id='" + text + "']" );
574     }
575
576     public void clickButtonWithName( String text, boolean wait )
577     {
578         clickLinkWithXPath( "//input[@name='" + text + "']", wait );
579     }
580
581     public void clickButtonWithValue( String text )
582     {
583         clickButtonWithValue( text, false );
584     }
585
586     public void clickButtonWithValue( String text, boolean wait )
587     {
588         assertButtonWithValuePresent( text );
589
590         if ( isElementPresent( "//button[@value='" + text + "']" ) )
591         {
592             clickLinkWithXPath( "//button[@value='" + text + "']", wait );
593         }
594         else
595         {
596             clickLinkWithXPath( "//input[@value='" + text + "']", wait );
597         }
598     }
599
600     public void clickSubmitWithLocator( String locator )
601     {
602         clickLinkWithLocator( locator );
603     }
604
605     public void clickSubmitWithLocator( String locator, boolean wait )
606     {
607         clickLinkWithLocator( locator, wait );
608     }
609
610     public void clickImgWithAlt( String alt )
611     {
612         clickLinkWithLocator( "//img[@alt='" + alt + "']" );
613     }
614
615     public void clickLinkWithText( String text )
616     {
617         clickLinkWithText( text, false );
618     }
619
620     public void clickLinkWithText( String text, boolean wait )
621     {
622         clickLinkWithLocator( "//*[text()='" + text +"']//ancestor::a", wait );
623     }
624
625     public void clickLinkWithXPath( String xpath )
626     {
627         clickLinkWithXPath( xpath, false );
628     }
629
630     public void clickLinkWithXPath( String xpath, boolean wait )
631     {
632         clickLinkWithLocator( xpath, wait );
633     }
634
635     public void clickLinkWithLocator( String locator )
636     {
637         clickLinkWithLocator( locator, false );
638     }
639
640     public void clickLinkWithLocator( String locator, boolean wait )
641     {
642         assertElementPresent( locator );
643         findElement(locator).click();
644         if ( wait )
645         {
646             waitPage();
647         }
648     }
649
650     public void clickButtonWithLocator( String locator )
651     {
652         clickButtonWithLocator( locator, false );
653     }
654
655     public void clickButtonWithLocator( String locator, boolean wait )
656     {
657         assertElementPresent( locator );
658         findElement(locator ).click();
659         if ( wait )
660         {
661             waitPage();
662         }
663     }
664
665     public <V> V tryClick(By clickableLocator, Function<? super WebDriver, V> conditions, String message, int attempts, int maxWaitTimeInS) {
666
667         getWebDriver().manage().window().maximize();
668         int count = attempts;
669         WebDriverWait wait = new WebDriverWait( getWebDriver(), maxWaitTimeInS );
670         V result = null;
671         Exception ex = null;
672         WebElement el = null;
673         while(count>0)
674         {
675             try
676             {
677                 el = wait.until(ExpectedConditions.elementToBeClickable( clickableLocator ));
678                 Actions actions = new Actions(getWebDriver());
679                 actions.moveToElement(el).click().perform();
680                 result = wait.until( conditions  );
681                 return result;
682             } catch (Exception e) {
683                 logger.info("Error: {}, {}, {}",count,e.getClass().getName(), e.getMessage());
684                 if (el!=null) {
685                     // Elements may be stale and throw an exception, if the location is requested
686                     try
687                     {
688                         Point elLoc = el.getLocation();
689                         logger.info( "Location: x={} y={}", elLoc.getX(), elLoc.getY() );
690                     } catch (Throwable e2) {
691                         logger.info("Could not determine location");
692                     }
693                 }
694                 ex = e;
695                 count--;
696             }
697             try
698             {
699                 Thread.currentThread().sleep(500);
700             }
701             catch ( InterruptedException e )
702             {
703                 // Ignore
704             }
705         }
706         if (ex!=null) {
707             Assert.fail( message);
708         }
709         return result;
710     }
711
712     /**
713      * Executes click() on the WebElement <code>el</code> and waits for the conditions.
714      * If the condition is not fulfilled in <code>maxWaitTimeInS</code>, the click is executed again
715      * and waits again for the condition.
716      * After the number of attempts as given by the parameter an assertion error will be thrown, with
717      * the given <code>message</code>.
718      *
719      * If the click was successful the element is returned that was created by the condition.
720      *
721      * @param el The element where the click is executed
722      * @param conditions The conditions to wait for after the click
723      * @param message The assertion messages
724      * @param attempts Maximum number of click attempts
725      * @param maxWaitTimeInS The time in seconds to wait that the condition is fulfilled.
726      * @param <V> The return type
727      * @return
728      */
729     public <V> V tryClick( WebElement el, Function<? super WebDriver, V> conditions, String message, int attempts, int maxWaitTimeInS)
730     {
731         int count = attempts;
732         WebDriverWait wait = new WebDriverWait( getWebDriver(), maxWaitTimeInS );
733         V result = null;
734         Exception ex = null;
735         while(count>0)
736         {
737             if (count<attempts) {
738                 try
739                 {
740                     result = conditions.apply( getWebDriver() );
741                     return result;
742                 } catch (Exception e) {
743                     // Ignore
744                 }
745             }
746             el.click();
747             try
748             {
749                 result = wait.until( conditions  );
750                 return result;
751             } catch (Exception e) {
752                 logger.info("Error: {}, {}",count, e.getMessage());
753                 ex = e;
754                 count--;
755             }
756             try
757             {
758                 Thread.currentThread().sleep(500);
759             }
760             catch ( InterruptedException e )
761             {
762                 // Ignore
763             }
764         }
765         if (ex!=null) {
766             Assert.fail( message);
767         }
768         return result;
769     }
770
771     public <V> V tryClick(WebElement el, Function<? super WebDriver, V> conditions, String message, int attempts )
772     {
773         return tryClick( el, conditions, message, attempts, 10 );
774     }
775
776     public <V> V tryClick(WebElement el, Function<? super WebDriver, V> conditions, String message)
777     {
778         return tryClick( el, conditions, message, 3);
779     }
780
781
782     public void setFieldValues( Map<String, String> fieldMap )
783     {
784         Map.Entry<String, String> entry;
785
786         for ( Iterator<Entry<String, String>> entries = fieldMap.entrySet().iterator(); entries.hasNext(); )
787         {
788             entry = entries.next();
789
790             setFieldValue( entry.getKey(), entry.getValue() );
791         }
792     }
793
794     public void setFieldValue( String fieldName, String value )
795     {
796         findElement(fieldName ).sendKeys( value );
797     }
798
799     public void checkField( String locator )
800     {
801         WebElement element = findElement(locator );
802         if (!element.isSelected()) {
803             element.click();
804         }
805     }
806
807     public void uncheckField( String locator )
808     {
809         WebElement element = findElement(locator );
810         if (element.isSelected()) {
811             element.click();
812         }
813     }
814
815     public boolean isChecked( String locator )
816     {
817         return findElement(locator ).isSelected();
818     }
819
820     public void assertIsChecked( String locator )
821     {
822
823         Assert.assertTrue( isChecked( locator ));
824     }
825
826     public void assertIsNotChecked( String locator )
827     {
828
829         Assert.assertFalse( isChecked( locator ) );
830     }
831
832
833
834     public String captureScreenShotOnFailure( Throwable failure, String methodName, String className )
835     {
836         SimpleDateFormat sdf = new SimpleDateFormat( "yyyy.MM.dd-HH_mm_ss" );
837         String time = sdf.format( new Date() );
838         Path targetPath = Paths.get( "target", "screenshots" );
839
840         int lineNumber = 0;
841
842         for ( StackTraceElement stackTrace : failure.getStackTrace() )
843         {
844             if ( stackTrace.getClassName().equals( this.getClass().getName() ) )
845             {
846                 lineNumber = stackTrace.getLineNumber();
847                 break;
848             }
849         }
850
851         try {
852             Files.createDirectories(targetPath);
853         } catch (IOException e) {
854             logger.error("Could not create directory {}: {}", targetPath, e.getMessage(), e);
855         }
856         if (getWebDriver()!=null)
857         {
858             String fileBaseName = methodName + "_" + className + ".java_" + lineNumber + "-" + time;
859             Path fileName = targetPath.resolve( fileBaseName + ".png" );
860             Path screenshot = WebdriverUtility.takeScreenShot( fileName.getFileName().toString(), getWebDriver());
861             return fileName.toAbsolutePath().toString();
862         } else {
863             return "";
864         }
865     }
866
867 }