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