View Javadoc
1   /**
2    * Copyright 2005-2016 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.testtools.selenium;
17  
18  import org.junit.After;
19  import org.junit.AfterClass;
20  import org.junit.Before;
21  import org.junit.BeforeClass;
22  import org.junit.Rule;
23  import org.junit.rules.TestName;
24  import org.kuali.rice.testtools.common.JiraAwareFailable;
25  import org.kuali.rice.testtools.common.JiraAwareFailureUtils;
26  import org.openqa.selenium.By;
27  import org.openqa.selenium.JavascriptExecutor;
28  import org.openqa.selenium.Keys;
29  import org.openqa.selenium.NoSuchElementException;
30  import org.openqa.selenium.NoSuchWindowException;
31  import org.openqa.selenium.WebDriver;
32  import org.openqa.selenium.WebElement;
33  import org.openqa.selenium.chrome.ChromeDriverService;
34  import org.openqa.selenium.interactions.Actions;
35  import org.openqa.selenium.remote.RemoteWebDriver;
36  
37  import java.lang.reflect.Method;
38  import java.text.SimpleDateFormat;
39  import java.util.ArrayList;
40  import java.util.Calendar;
41  import java.util.Date;
42  import java.util.Iterator;
43  import java.util.LinkedList;
44  import java.util.List;
45  import java.util.Set;
46  import java.util.concurrent.TimeUnit;
47  
48  /**
49   * Ideally the AFT code here should be generic for KRAD AFT testing and not specific to KRAD sampleapp testing.  The idea
50   * being that code in this class should be generic enough to be useful to other projects using and testing KRAD without having
51   * to pull in code to specific to the KRAD sampleapp.  KRAD sampleapp specific code should go in WebDriverLegacyITBase.
52   *
53   * @author Kuali Rice Team (rice.collab@kuali.org)
54   */
55  public abstract class WebDriverAftBase extends JiraAwareAftBase {
56  
57      protected static ChromeDriverService chromeDriverService;
58  
59      /**
60       * div.dataTables_wrapper thead th
61       */
62      public static final String DATA_TABLE_TH_CSS = "div.dataTables_wrapper thead th";
63  
64      // make WebDriver static for one browser
65      protected WebDriver driver;
66  
67      protected String jGrowlHeader;
68  
69      /**
70       *  lookupCriteria[number]
71       */
72      public static final String LOOKUP_CRITERIA_NUMBER_NAME="lookupCriteria[number]";
73  
74      /**
75       * ^[\s\S]*error[\s\S]*$"
76       */
77      public static final String REGEX_ERROR = "^[\\s\\S]*error[\\s\\S]*$";
78  
79      /**
80       * ^[\s\S]*valid[\s\S]*$
81       */
82      public static final String REGEX_VALID = "^[\\s\\S]*valid[\\s\\S]*$";
83  
84      /**
85       * return selected
86       */
87      public static final String RETURN_SELECTED_BUTTON_TEXT = "return selected";
88  
89      /**
90       * return value
91       */
92      public static final String RETURN_VALUE_LINK_TEXT = "return value";
93  
94      /**
95       * //button[contains(text(),'earch')]
96       */
97      public static final String SEARCH_XPATH_3 = "//button[contains(text(),'earch')]";
98  
99      /**
100      * show inactive
101      */
102     public static final String SHOW_INACTIVE = "show inactive";
103 
104     /**
105      * div.uif-group.uif-collectionGroup.uif-tableCollectionGroup.uif-tableSubCollection.uif-disclosure span.uif-headerText-span
106      */
107     public static final String SUB_COLLECTION_UIF_DISCLOSURE_SPAN_UIF_HEADER_TEXT_SPAN_XPATH =
108             "div.uif-group.uif-collectionGroup.uif-tableCollectionGroup.uif-tableSubCollection.uif-disclosure span.uif-headerText-span";
109 
110     // one browser
111 //    protected String oneBrowserHandle = null;
112 
113     protected String sessionId = null;
114 
115     protected String testMethodName;
116 
117     public @Rule TestName testName = new TestName();
118 
119     /**
120      * timeout
121      */
122     public static final String TIMEOUT_MESSAGE = "timeout";
123 
124     protected String uniqueString;
125 
126     protected String user = "admin";
127 
128     protected int waitSeconds;
129 
130     protected WebDriverScreenshotHelper webDriverScreenshotHelper = new WebDriverScreenshotHelper();
131 
132     protected void acceptAlertIfPresent() {
133         WebDriverUtils.acceptAlertIfPresent(driver);
134     }
135 
136     /**
137      * Accept the javascript alert (clicking OK)
138      */
139     protected void alertAccept() {
140         WebDriverUtils.alertAccept(driver);
141     }
142 
143     /**
144      * Dismiss the javascript alert (clicking Cancel)
145      */
146     protected void alertDismiss() {
147         WebDriverUtils.alertDismiss(driver);
148     }
149 
150     @AfterClass
151     public static void afterClass() {
152         // one browser
153 //        if (driver != null) {
154 //            try {
155 //                driver.close();
156 //            } catch (NoSuchWindowException nswe) {
157 //                System.out.println("NoSuchWindowException closing WebDriver " + nswe.getMessage());
158 //            } finally {
159 //                if (driver != null) {
160 //                    driver.quit();
161 //                }
162 //            }
163 //        }
164 
165         if (chromeDriverService != null) {
166             chromeDriverService.stop();
167         }
168     }
169 
170     protected boolean areAllMultiValueSelectsChecked() throws InterruptedException {
171         acceptAlertIfPresent();
172         WebElement tbody = waitAndGetElementByAttributeValue("role", "alert"); // results table body
173         List<WebElement> checkboxes = findElements(By.className("uif-checkboxControl"),tbody);
174         for (WebElement checkbox: checkboxes) {
175             if (!"true".equals(checkbox.getAttribute("checked"))) {
176                 return false;
177             }
178         }
179         return true;
180     }
181 
182     protected boolean areNoMultiValueSelectsChecked() throws InterruptedException {
183         WebElement tbody = waitAndGetElementByAttributeValue("role", "alert"); // results table body
184         List<WebElement> checkboxes = findElements(By.className("uif-checkboxControl"),tbody);
185         for (WebElement checkbox: checkboxes) {
186             if (null != checkbox.getAttribute("checked")) {
187                 return false;
188             }
189         }
190         return true;
191     }
192 
193     protected void assertAttributeClassRegexDoesntMatch(String field, String regex) throws InterruptedException {
194         Thread.sleep(1000);
195         String attribute = waitAndGetAttributeByName(field, "class");
196         assertTrue("waitAndGetAttributeByName(" + field + ", \"class\") should not be null", attribute != null);
197         assertFalse("attribute " + attribute + " matches regex " + regex + " and it should not", attribute.matches(
198                 regex));
199     }
200 
201     protected void assertAttributeClassRegexMatches(String field, String regex) throws InterruptedException {
202         Thread.sleep(1000);
203         String attribute = waitAndGetAttributeByName(field, "class");
204         assertTrue("waitAndGetAttributeByName(" + field + ", \"class\") should not be null", attribute != null);
205         assertTrue("attribute " + attribute + " doesn't match regex " + regex, attribute.matches(regex));
206     }
207 
208     protected void assertElementPresentInResultPages(By searchBy) throws Exception {
209         while(!isElementPresent(searchBy)) {
210             assertTrue("Didn't find expected results in result pages", isNextLinkEnabled());
211             waitAndClickByLinkText("Next");
212         }
213     }
214 
215     protected void assertElementsPresentInResultPages(By[] searchBys) throws Exception {
216         boolean[] founds = new boolean[searchBys.length];
217         boolean allFound = false;
218 
219         waitForElementPresentById("uLookupResults_layout_next");
220 
221         while (!allFound) {
222 
223             for (int i = 0; i < founds.length; i++) {
224                 if (!founds[i]) {
225                     founds[i] = isElementPresent(searchBys[i]);
226                 }
227             }
228 
229             allFound = true; // assume we found them all, verify that assumption in the for loop
230             for (int i = 0; i < founds.length; i++) {
231                 if (!founds[i]) {
232                     allFound = false;
233                 }
234             }
235 
236             if (!allFound) {
237                 assertTrue("Didn't find expected results in result pages for " + this.getClass().getSimpleName(), isNextLinkEnabled());
238                 waitAndClickByLinkText("Next");
239             }
240 
241         }
242     }
243 
244     protected void assertTextPresentInResultPages(String[][] texts) throws Exception {
245         boolean[] founds = new boolean[texts.length];
246         boolean allFound = false;
247 
248         waitForElementPresentById("uLookupResults_layout_next");
249 
250         while (!allFound) {
251 
252             for (int i = 0; i < founds.length; i++) {
253                 if (!founds[i]) {
254                     for (int j = 0; j < texts.length; j++) {
255                         founds[i] = isTextPresent(texts[i]);
256                     }
257                 }
258             }
259 
260             allFound = true; // assume we found them all, verify that assumption in the for loop
261             for (int i = 0; i < founds.length; i++) {
262                 if (!founds[i]) {
263                     allFound = false;
264                 }
265             }
266 
267             if (!allFound) {
268                 assertTrue("Didn't find expected results in result pages for " + this.getClass().getSimpleName(), isNextLinkEnabled());
269                 waitAndClickByLinkText("Next");
270             }
271         }
272     }
273 
274 
275     protected void assertEmptyInputByName(String name) throws InterruptedException {
276         assertTrue(name + " not empty for " + this.getClass().getSimpleName(), waitForElementPresentByName(name)
277                 .getAttribute("value").equals(""));
278     }
279 
280     protected void assertFocusTypeBlurError(String field, String textToType) throws InterruptedException {
281         fireEvent(field, "focus");
282         waitAndTypeByName(field, textToType);
283         fireEvent(field, "blur");
284         Thread.sleep(500);
285         assertAttributeClassRegexMatches(field, REGEX_ERROR);
286         clearTextByName(field);
287     }
288 
289     protected void assertFocusTypeBlurError(String field, String[] errorInputs) throws InterruptedException {
290         for (String errorInput: errorInputs) {
291             assertFocusTypeBlurError(field, errorInput);
292             clearTextByName(field);
293         }
294     }
295 
296     protected void assertFocusTypeBlurValid(final String field, String textToType) throws InterruptedException {
297         clearTextByName(field);
298         fireEvent(field, "focus");
299         waitAndTypeByName(field, textToType);
300         fireEvent(field, "blur");
301         Thread.sleep(200);
302         assertAttributeClassRegexMatches(field, REGEX_VALID);
303         assertAttributeClassRegexDoesntMatch(field, REGEX_ERROR);
304         clearTextByName(field);
305     }
306 
307     protected void assertFocusTypeBlurValid(String field, String[] validInputs) throws InterruptedException {
308         for (String validInput: validInputs) {
309             assertFocusTypeBlurValid(field, validInput);
310             clearTextByName(field);
311         }
312     }
313 
314     protected void assertFocusTypeBlurValidation(String field, String[] errorInputs, String[] validInputs) throws InterruptedException {
315         assertFocusTypeBlurError(field, errorInputs);
316         clearTextByName(field);
317         assertFocusTypeBlurValid(field, validInputs);
318     }
319 
320     protected void assertFocusTypeTabError(String field, String textToType) throws InterruptedException {
321         fireEvent(field, "focus");
322         waitAndTypeByName(field, textToType);
323         driver.switchTo().activeElement().sendKeys(Keys.TAB);
324         Thread.sleep(500);
325         assertAttributeClassRegexMatches(field, REGEX_ERROR);
326         clearTextByName(field);
327     }
328 
329     protected void assertJgrowlText(String jGrowlText) throws InterruptedException {
330         waitForElementPresentByClassName("jGrowl-message");
331 
332         // wait for any flash not present errors to fade out
333         while (jGrowlTextContains("Unable to load SWF file")) {
334             try {
335                 driver.findElement(By.className("jGrowl-close")).click(); // no wait, click quick
336             } catch (Throwable t) {
337                 // don't fail because the swf jgrowl has gone away
338             }
339         }
340 
341         // get growl texts
342         StringBuilder sb = new StringBuilder("");
343         List<WebElement> jGrowls = findElements(By.className("jGrowl-message"));
344         for (WebElement jGrowl : jGrowls) {
345             if (jGrowl.getText() != null) {
346                 sb.append(jGrowl.getText()).append("\n");
347             }
348         }
349         String growlText = sb.toString();
350 
351         WebDriverUtils.stepMessage("Do jGrowls contain text '" + jGrowlText + "'? " + growlText.contains(jGrowlText));
352 
353         //check growl text is present
354         assertTrue(growlText + " does not contain " + jGrowlText, growlText.contains(jGrowlText));
355     }
356 
357     private boolean jGrowlTextContains(String text) {
358         boolean contains = false;
359         try {
360             contains = findElement(By.className("jGrowl-message")).getText().contains(text);
361         } catch (Throwable t) {
362             return false;
363         }
364         return contains;
365     }
366 
367     protected void assertLabelWithTextPresent(String labelText) throws InterruptedException {
368         jGrowl("Assert Label containing the text " + labelText + " is present");
369         waitForElementPresentByXpath("//label[contains(text(), '" + labelText + "')]");
370     }
371 
372     protected void assertLabelFor(String forElementId, String labelText) {
373         assertEquals(labelText, getForLabelText(forElementId));
374     }
375 
376     protected void assertMultiValueDeselectAllThisPage() throws InterruptedException {
377         waitAndClickDropDown("deselect all items on this page");
378         if (!areNoMultiValueSelectsChecked()) {
379             jiraAwareFail("deselect all items on this page failure");
380         }
381         assertButtonDisabledByText(RETURN_SELECTED_BUTTON_TEXT);
382     }
383 
384     protected void assertMultiValueSelectAllThisPage() throws InterruptedException {
385         waitAndClickDropDown("select all items on this page");
386         if (!areAllMultiValueSelectsChecked()) {
387             JiraAwareFailureUtils.fail("select all items on this page failure", this);
388         }
389         assertButtonEnabledByText(RETURN_SELECTED_BUTTON_TEXT);
390     }
391 
392     protected void assertTextPresent(String[] text) throws InterruptedException {
393         assertTextPresent("", text);
394     }
395 
396     protected void assertTextPresent( String message, String[] text) throws InterruptedException {
397         StringBuilder missingText = new StringBuilder("");
398         boolean present = true;
399         for (int i = 0, s = text.length; i < s; i++) {
400             if (i == 0) {
401                 present = waitForIsTextPresent(text[0]); // wait for the first check
402                 if (!present) {
403                     missingText.append(text[0]);
404                 }
405             } else {
406                 if (!isTextPresent(text[i])) {
407                     present = false;
408                     missingText.append(" " + text[i]);
409                 }
410             }
411         }
412         if (!present) {
413             jiraAwareFail(message + " " + missingText + " not present for " + this.getClass().toString());
414         }
415     }
416 
417     protected void assertTextPresent(String[][] text) throws InterruptedException {
418         StringBuilder missingText = new StringBuilder("");
419         boolean present = true;
420         for (int i = 0, s = text.length; i < s; i++) {
421             for (int j = 0, t = text[i].length; j < t; j++) {
422                 if (i == 0 && j == 0) {
423                     present = waitForIsTextPresent(text[0][0]); // wait for the first check
424                     if (!present) {
425                         missingText.append(text[0][0]);
426                     }
427                 } else {
428                     if (!isTextPresent(text[i][j])) {
429                         present = false;
430                         missingText.append(" " + text[i][j]);
431                     }
432                 }
433             }
434         }
435         if (!present) {
436             jiraAwareFail(missingText + " not present for " + this.getClass().toString());
437         }
438     }
439 
440     /**
441      * Assert that clicking an element causes a popup window with a specific URL
442      * Uses Selenium's findElements method which does not throw a test exception if not found.
443      * @param by The locating mechanism of the element to be clicked
444      * @param windowName The name of the popup window
445      * @param url The URL of the popup window
446      */
447     protected void assertPopUpWindowUrl(By by, String windowName, String url) {
448         findElement(by).click();
449         String parentWindowHandle = driver.getWindowHandle();
450         // wait page to be loaded
451         driver.switchTo().window(windowName).findElements(By.tagName("head"));
452         assertEquals(url, driver.getCurrentUrl());
453         driver.switchTo().window(parentWindowHandle);
454     }
455 
456     protected void back() {
457         jGrowl("Click browser back button");
458         driver.navigate().back();
459     }
460 
461     protected void check(By by) throws InterruptedException {
462         WebElement element = findElement(by);
463 
464         if (!element.isSelected()) {
465             element.click();
466         }
467     }
468 
469     protected void checkById(String id) throws InterruptedException {
470         check(By.id(id));
471     }
472 
473     protected void checkByName(String name) throws InterruptedException {
474         check(By.name(name));
475     }
476 
477     protected void checkByXpath(String locator) throws InterruptedException {
478         check(By.xpath(locator));
479     }
480 
481     protected void checkForIncidentReport() {
482         checkForIncidentReport("", this.getClass().toString());
483     }
484 
485     protected String incidentReportMessage() {
486         return AutomatedFunctionalTestUtils.incidentReportMessage(driver.getPageSource(), "", this.getClass().toString());
487     }
488 
489     protected void checkForIncidentReport(String locator) {
490         checkForIncidentReport(locator, this.getClass().toString());
491     }
492 
493     protected void checkForIncidentReport(String locator, String message) {
494         AutomatedFunctionalTestUtils.checkForIncidentReport(driver.getPageSource(), locator, message, this);
495     }
496 
497     /**
498      * @deprecated {@see #checkForIncidentReport(String, String)}
499      */
500     protected void checkForIncidentReport(String locator, JiraAwareFailable failable, String message) {
501         AutomatedFunctionalTestUtils.checkForIncidentReport(driver.getPageSource(), locator, message, failable);
502     }
503 
504     protected void clearText(By by) throws InterruptedException {
505         findElement(by).clear();
506     }
507 
508     protected void clearText(String selector) throws InterruptedException {
509         clearText(By.cssSelector(selector));
510     }
511 
512     protected void clearTextByName(String name) throws InterruptedException {
513         clearText(By.name(name));
514     }
515 
516     protected void clearTextByXpath(String locator) throws InterruptedException {
517         clearText(By.xpath(locator));
518     }
519 
520     protected void close() {
521         driver.close();
522     }
523 
524     protected void closeAllOtherWindows(String handleToKeep) {
525         Set<String> set = driver.getWindowHandles();
526 
527         set.remove(handleToKeep);
528 
529         Iterator iter = set.iterator();
530         String handle = "";
531         while (iter.hasNext()) {
532             handle = (String)iter.next();
533             driver.switchTo().window(handle);
534             driver.close();
535         }
536 
537         driver.switchTo().window(handleToKeep);
538     }
539 
540 
541     protected void colapseExpandByXpath(String clickLocator, String visibleLocator) throws InterruptedException {
542         waitAndClickByXpath(clickLocator);
543         waitNotVisibleByXpath(visibleLocator);
544         waitAndClickByXpath(clickLocator);
545         waitIsVisibleByXpath(visibleLocator);
546     }
547 
548     /**
549      * If WebDriverUtils.chromeDriverCreateCheck() returns a ChromeDriverService, start it.
550      * {@link org.kuali.rice.testtools.selenium.WebDriverUtils#chromeDriverCreateCheck()}
551      * @throws Exception
552      */
553     @BeforeClass
554     public static void chromeDriverService() throws Exception {
555         chromeDriverService = WebDriverUtils.chromeDriverCreateCheck();
556         if (chromeDriverService != null) {
557             chromeDriverService.start();
558         }
559 
560 // one browser
561 //        driver = WebDriverUtils.setUp("getClass().getSimpleName()", "testMethodName");
562 
563     }
564 
565     protected void closeAndQuitWebDriver() {
566         if (driver != null) {
567             if (WebDriverUtils.dontTearDownPropertyNotSet() && WebDriverUtils.dontTearDownOnFailure(isPassed())) {
568                 try {
569                     acceptAlertIfPresent();
570                     driver.close();
571                 } catch (NoSuchWindowException nswe) {
572                     System.out.println("NoSuchWindowException closing WebDriver " + nswe.getMessage());
573                 } finally {
574                     if (driver != null) {
575                         driver.quit();
576                     }
577                 }
578             }
579         } else {
580             System.out.println("WebDriver is null for " + this.getClass().toString() + " if using a remote hub did you include the port?");
581         }
582     }
583 
584     protected void determineImplicitWait() {
585         waitSeconds = WebDriverUtils.configuredImplicityWait();
586     }
587 
588     protected void determineJgrowlHeader() {
589         jGrowlHeader = getClass().getSimpleName() + "." + testMethodName;
590     }
591 
592     protected String determinePage() {
593         String url = driver.getCurrentUrl();
594 
595         String viewId = "";
596         if (url.contains("viewId=")) {
597             viewId = url.substring(url.indexOf("viewId=") + 7, url.length());
598             if (viewId.indexOf("&") > -1) {
599                 viewId = viewId.substring(0, viewId.indexOf("&"));
600             } else {
601                 viewId = viewId.substring(0, viewId.length());
602             }
603         }
604 
605         String pageId = "";
606         if (url.contains("pageId=")) {
607             pageId = url.substring(url.indexOf("pageId=") + 7, url.length());
608             if (pageId.indexOf("&") > -1) {
609                 pageId = "-" + pageId.substring(0, pageId.indexOf("&"));
610             } else {
611                 pageId = "-" + pageId.substring(0, pageId.length());
612             }
613         }
614 
615         return viewId + pageId;
616     }
617 
618     protected void determineTestMethodName() {
619         if (testName != null && testName.getMethodName() != null) { // JUnit
620             setTestMethodName(testName.getMethodName());
621         }
622     }
623 
624     public void setTestMethodName(String testMethodName) {
625         this.testMethodName = testMethodName;
626     }
627 
628     protected void determineUser() {
629         String givenUser = WebDriverUtils.determineUser(this.toString());
630         if (givenUser != null) {
631             user = givenUser;
632         }
633     }
634 
635     protected String getDescriptionBase() {
636         return this.getClass().toString().substring(this.getClass().toString().lastIndexOf(".") + 1,
637                 this.getClass().toString().length()) +
638                 "." + testMethodName + " description";
639     }
640 
641     protected String getDescriptionUnique() {
642         if (uniqueString == null) {
643             uniqueString = AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomCharsNot9Digits();
644         }
645         return getDescriptionBase() + " " + uniqueString;
646     }
647 
648     protected WebElement findButtonByText(String buttonText) {
649         return WebDriverUtils.findButtonByText(driver, buttonText);
650     }
651 
652     protected List<WebElement> findVisibleElements(By by) {
653         List<WebElement> webElements = driver.findElements(by);
654         List<WebElement> visibleWebElements = new LinkedList<WebElement>();
655         for (WebElement webElement: webElements) {
656             if (webElement.isDisplayed()) {
657                 visibleWebElements.add(webElement);
658             }
659         }
660 
661         return visibleWebElements;
662     }
663 
664     protected List<WebElement> findElements(By by) {
665         List<WebElement> found = driver.findElements(by);
666         return found;
667     }
668 
669     protected List<WebElement> findElements(By by, WebElement element) {
670         if (element == null) {
671             checkForIncidentReport();
672             throw new AssertionError("element to findElements on for " + by.toString() + " is null in class " + this.getClass().toString());
673         }
674         List<WebElement> found = element.findElements(by);
675         return found;
676     }
677 
678     protected void fireEvent(String name, String event) {
679         ((JavascriptExecutor) driver).executeScript("var elements=document.getElementsByName(\"" + name + "\");" +
680                 "for (var i = 0; i < elements.length; i++){" +
681                 "elements[i]." + event + "();}");
682     }
683 
684     protected void fireEvent(String name, String value, String event) {
685         ((JavascriptExecutor) driver).executeScript("var elements=document.getElementsByName(\"" + name + "\");" +
686                 "for (var i = 0; i < elements.length; i++){" +
687                 "if(elements[i].value=='" + value + "')" +
688                 "elements[i]." + event + "();}");
689     }
690 
691     /**
692      * {@link org.openqa.selenium.interactions.Actions#moveToElement(org.openqa.selenium.WebElement)}
693      * @param name
694      */
695     public void fireMouseOverEventByName(String name) {
696         this.fireMouseOverEvent(By.name(name));
697     }
698 
699     /**
700      * {@link org.openqa.selenium.interactions.Actions#moveToElement(org.openqa.selenium.WebElement)}
701      * @param id
702      */
703     public void fireMouseOverEventById(String id) {
704         this.fireMouseOverEvent(By.id(id));
705     }
706 
707     /**
708      * {@link org.openqa.selenium.interactions.Actions#moveToElement(org.openqa.selenium.WebElement)}
709      * @param locator
710      */
711     public void fireMouseOverEventByXpath(String locator) {
712         this.fireMouseOverEvent(By.xpath(locator));
713     }
714 
715     /**
716      * {@link org.openqa.selenium.interactions.Actions#moveToElement(org.openqa.selenium.WebElement)}
717      * @param by
718      */
719     public void fireMouseOverEvent(By by) {
720         Actions builder = new Actions(driver);
721         Actions hover = builder.moveToElement(findElement(by));
722         hover.perform();
723     }
724 
725     /**
726      * {@link org.openqa.selenium.WebDriver#getWindowHandles()}
727      * @return
728      */
729     public String[] getAllWindowTitles() {
730         return (String[]) driver.getWindowHandles().toArray();
731     }
732 
733     protected String getBaseUrlString() {
734         return WebDriverUtils.getBaseUrlString();
735     }
736 
737     protected int getCssCount(String selector) {
738         return getCssCount(By.cssSelector(selector));
739     }
740 
741     /**
742      * Uses Selenium's findElements method which does not throw a test exception if not found.
743      * @param by
744      * @return
745      */
746     protected int getCssCount(By by) {
747         return (findElements(by)).size();
748     }
749 
750     protected String getDateTimeStampFormatted() {
751         return WebDriverUtils.getDateTimeStampFormatted();
752     }
753 
754     protected String getDateToday() {
755         Date now = Calendar.getInstance().getTime();
756         SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
757         return sdf.format(now);
758     }
759 
760     protected String getDateTomorrow() {
761         Calendar now = Calendar.getInstance();
762         now.add(Calendar.DATE, 1);
763         SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
764         return sdf.format(now.getTime());
765     }
766 
767     /**
768      * {@inheritDoc}
769      *
770      * @return WebDriver
771      */
772     @Override
773     protected WebDriver getDriver() {
774         return driver;
775     }
776 
777     public void setDriver(WebDriver driver) {
778         this.driver = driver;
779     }
780 
781     protected WebElement getElementByAttribute(String attributeName){
782         return findElement(By.cssSelector("[" + attributeName + "]"));
783     }
784 
785     protected WebElement getElementByDataAttribute(String dataAttributeName){
786         return findElement(By.cssSelector("[data-" + dataAttributeName + "]"));
787     }
788 
789     protected WebElement getElementByDataAttributeValue(String dataAttributeName, String value){
790         return findElement(By.cssSelector("[data-" + dataAttributeName + "='" + value + "']"));
791     }
792 
793     protected WebElement getElementByAttributeValue(String attributeName, String value){
794         return findElement(By.cssSelector("[" + attributeName + "='" + value +"']"));
795     }
796 
797     protected List<WebElement> getElementsByAttributeValue(String attributeName, String value){
798         return findElements(By.cssSelector("[" + attributeName + "='" + value + "']"));
799     }
800 
801     @Override
802     protected String getNavigationUrl() {
803         String classString = this.getClass().toString();
804         if (classString.contains("krad.demo")) {
805             return AutomatedFunctionalTestUtils.KRAD_PORTAL;
806         } else if (classString.contains("krad.labs")) {
807             return AutomatedFunctionalTestUtils.LABS;
808         } else {
809             return AutomatedFunctionalTestUtils.PORTAL;
810         }
811     }
812 
813     /**
814      * Uses Selenium's findElements for getting the options (findElement for the select) method which does not throw a test exception if not found.
815      * @param by
816      * @return
817      * @throws InterruptedException
818      */
819     protected String[] getSelectOptions(By by) throws InterruptedException {
820         WebElement select1 = driver.findElement(by); // don't highlight
821         List<WebElement> options = select1.findElements(By.tagName("option"));
822         String[] optionValues = new String[options.size()];
823         int counter = 0;
824 
825         for (WebElement option : options) {
826             optionValues[counter] = option.getAttribute("value");
827             counter++;
828         }
829 
830         return optionValues;
831     }
832 
833     protected String[] getSelectOptionsByName(String name) throws InterruptedException {
834         return getSelectOptions(By.name(name));
835     }
836 
837     protected String[] getSelectOptionsByXpath(String locator) throws InterruptedException {
838         return getSelectOptions(By.xpath(locator));
839     }
840 
841     /**
842      *
843      * @return sessionId
844      */
845     public String getSessionId() {
846         return sessionId;
847     }
848 
849     protected String getText(By by) throws InterruptedException {
850         WebElement element = findElement(by);
851         return element.getText();
852     }
853 
854     protected String getTextByClassName(String className) throws InterruptedException {
855         return getText(By.className(className));
856     }
857 
858     protected String getTextById(String id) throws InterruptedException {
859         return getText(By.id(id));
860     }
861 
862     protected String getTextByName(String name) throws InterruptedException {
863         return getText(By.name(name));
864     }
865 
866     protected String getText(String locator) throws InterruptedException {
867         return getText(By.cssSelector(locator));
868     }
869 
870     protected String getTextByXpath(String locator) throws InterruptedException {
871         return getText(By.xpath(locator));
872     }
873 
874     protected String getTitle() {
875         return driver.getTitle();
876     }
877 
878     /**
879      * "admin" by default.  Can be overridden using {@see WebDriverUtils#REMOTE_PUBLIC_USER_PROPERTY}
880      * @return string
881      */
882     public String getUserName() {
883         return user;
884     }
885 
886     /**
887      * Returns the label text of a label-for element
888      * <p>
889      * For usage with elements like this: <label for="some-element-id">The text of the Label</label>
890      * </p>
891      *
892      * @param forElementId the id of the element for which to find the label text
893      * @return label text
894      */
895     protected String getForLabelText(String forElementId) {
896         return findElement(By.cssSelector("label[for=" + forElementId + "]")).getText();
897     }
898 
899     protected void gotoIframeById(final String iframeId) {
900         if (driver.findElements(By.id(iframeId)).size() > 0) { // find elements so an exception isn't thrown if not found
901             WebElement contentFrame = driver.findElement(By.id(iframeId)); // don't highlight
902             driver.switchTo().frame(contentFrame);
903         } else {
904             System.out.println("Unable to find " + iframeId);
905         }
906     }
907     protected WebElement gotoIframeByXpath(final String iframeXpath) {
908         if (driver.findElements(By.xpath(iframeXpath)).size() > 0) {  // find elements so an exception isn't thrown if not found
909             WebElement contentFrame = driver.findElement(By.xpath(iframeXpath)); // don't highlight
910             driver.switchTo().frame(contentFrame);
911             return contentFrame;
912         } else {
913             System.out.println("Unable to find " + iframeXpath);
914         }
915         return null;
916     }
917 
918     protected void gotoLightBox() throws InterruptedException {
919         waitForElementVisibleBy(By.cssSelector(".uif-lookupDialog-iframe"));
920         driver.switchTo().frame(driver.findElement(By.cssSelector(".uif-lookupDialog-iframe")));
921     }
922 
923     protected WebElement gotoLightBoxIframe() {
924         selectTopFrame();
925         return gotoIframeByXpath("//iframe[@class='uif-iFrame uif-lookupDialog-iframe']");
926     }
927 
928     protected int howManyAreVisible(By by) throws InterruptedException {
929         int count = 0;
930         if (by == null) {
931 
932             return count;
933         }
934 
935         List<WebElement> webElementsFound = driver.findElements(by);
936         for (WebElement webElement: webElementsFound) {
937             if (webElement.isDisplayed()) {
938                 count++;
939             }
940         }
941 
942         return count;
943     }
944 
945     protected boolean isNextLinkEnabled() {
946         return findElements(By.xpath("//a[@id='uLookupResults_layout_next' and @class='next paginate_button paginate_button_disabled']")).size() != 1;
947     }
948 
949     protected boolean isChecked(By by) {
950         return findElement(by).isSelected();
951     }
952 
953     protected boolean isCheckedById(String id) {
954         return isChecked(By.id(id));
955     }
956 
957     protected boolean isCheckedByName(String name) {
958         return isChecked(By.name(name));
959     }
960 
961     protected boolean isCheckedByXpath(String locator) {
962         return isChecked(By.xpath(locator));
963     }
964 
965     protected boolean isEnabled(By by) {
966         return findElement(by).isEnabled();
967     }
968 
969     protected boolean isEnabledById(String id) {
970         return isEnabled(By.id(id));
971     }
972 
973     protected boolean isEnabledByName(String name) {
974         return isEnabled(By.name(name));
975     }
976 
977     protected boolean isEnabledByXpath(String locator) {
978         return isEnabled(By.xpath(locator));
979     }
980 
981     protected boolean isVisible(By[] bys) {
982         if (bys == null || bys.length == 0 ) {
983             return false;
984         }
985 
986         for (int i = 0, s = bys.length; i < s; i++) {
987 
988             try {
989 
990                 if (isVisible(bys[i])) {
991                     return true;
992                 }
993 
994             } catch (NoSuchElementException nsee) {
995                 // don't fail
996             }
997 
998         }
999 
1000         return false;
1001     }
1002 
1003     /**
1004      * Uses Selenium's findElements method which does not throw a test exception if not found.
1005      * @param by
1006      * @return
1007      */
1008     protected boolean isElementPresent(By by) {
1009         return (driver.findElements(by)).size() > 0;
1010     }
1011 
1012     /**
1013      * Uses Selenium's findElements method which does not throw a test exception if not found.
1014      * @param locator
1015      * @return
1016      */
1017     protected boolean isElementPresent(String locator) {
1018         return (driver.findElements(By.cssSelector(locator))).size() > 0;
1019     }
1020 
1021     protected boolean isElementPresentById(String id) {
1022         return isElementPresent(By.id(id));
1023     }
1024 
1025     protected boolean isElementPresentByName(String name) {
1026         return isElementPresent(By.name(name));
1027     }
1028 
1029     protected boolean isElementPresentByXpath(String locator) {
1030         return isElementPresent(By.xpath(locator));
1031     }
1032 
1033     protected boolean isElementPresentByLinkText(String locator) {
1034         return isElementPresent(By.linkText(locator));
1035     }
1036 
1037     protected boolean isElementPresentByDataAttributeValue(String dataAttributeName, String dataAttributeValue) {
1038         return isElementPresent(By.cssSelector("[data-" + dataAttributeName + "='" + dataAttributeValue + "']"));
1039     }
1040 
1041     protected boolean isNotVisible(By by) {
1042         return !(isVisible(by));
1043     }
1044 
1045     protected Boolean isTextPresent(String text) {
1046         return WebDriverUtils.isTextPresent(driver, driver.getPageSource(), text);
1047     }
1048 
1049     protected Boolean isTextPresent(String[] texts) {
1050         String pageSource = driver.getPageSource();
1051         for (String text: texts) {
1052             if (!WebDriverUtils.isTextPresent(driver, pageSource, text)) {
1053                 return false;
1054             }
1055         }
1056         return true;
1057     }
1058 
1059     protected void javascriptErrorsReport() {List javascriptErrors = WebDriverUtils.javascriptErrors(getDriver());
1060         if (javascriptErrors != null && javascriptErrors.size() > 0) {
1061             jGrowl("JAVASCRIPT ERRORS DETECTED - " + WebDriverUtils.javascriptErrorsToString(javascriptErrors));
1062         }
1063     }
1064 
1065     protected void jGrowl(String message) {
1066         WebDriverUtils.jGrowl(driver, jGrowlHeader, false, message);
1067         if (webDriverScreenshotHelper.screenshotSteps()) {
1068             screenshot();
1069         }
1070     }
1071 
1072     /**
1073      * Sticky is used on fail, making a call to jGrowl(String) from this method will result
1074      * in an infinite loop if JGROWL_ERROR_FAILURE is true so please don't.
1075      */
1076     protected void jGrowlSticky(String message) {
1077         WebDriverUtils.jGrowl(driver, jGrowlHeader, true, message);
1078         if (webDriverScreenshotHelper.screenshotSteps()) {
1079             screenshot();
1080         }
1081     }
1082 
1083     /**
1084      * <p>
1085      * Logs in using the KRAD Login Page, if the JVM arg remote.autologin is set, auto login as admin will not be done.
1086      * </p>
1087      *
1088      * @param driver to login with
1089      * @param userName to login with
1090      * @param failable to fail on if there is a login problem
1091      * @throws InterruptedException
1092      */
1093     public void login(WebDriver driver, String userName, JiraAwareFailable failable) throws InterruptedException {
1094         if ("true".equalsIgnoreCase(System.getProperty(WebDriverUtils.REMOTE_AUTOLOGIN_PROPERTY, "true"))) {
1095             driver.findElement(By.name("login_user")).clear();
1096             driver.findElement(By.name("login_user")).sendKeys(userName);
1097             driver.findElement(By.id("Rice-LoginButton")).click();
1098             Thread.sleep(1000);
1099             String contents = driver.getPageSource();
1100             AutomatedFunctionalTestUtils.failOnInvalidUserName(userName, contents, failable);
1101             AutomatedFunctionalTestUtils.checkForIncidentReport(driver.getPageSource(), "Login", "Login failure",
1102                     failable);
1103         }
1104     }
1105 
1106     protected void logout() throws InterruptedException {
1107         // KRAD Logout requires server configuration, currently env14 is not configured so throws Incident Report.
1108         //        } else {
1109         //            String logoutUrl = getBaseUrlString() + "/kr-krad/login?methodToCall=logout";
1110         //            jGrowl("Logging out with " + logoutUrl);
1111         //            open(logoutUrl);
1112     }
1113 
1114     protected String multiValueResultCount() throws InterruptedException {
1115         WebElement dataTableInfo = waitAndGetElementByAttributeValue("class", "dataTables_info");
1116         String resultsCount = dataTableInfo.getText();
1117         resultsCount = resultsCount.substring(resultsCount.indexOf(" of ") + 4, resultsCount.indexOf(" entries")).trim();
1118         return resultsCount;
1119     }
1120 
1121     protected void open(String url) {
1122         driver.get(url);
1123     }
1124 
1125     @Override
1126     protected void navigate() throws Exception {
1127         // No-op for convenience
1128     }
1129 
1130     protected void screenshot() {
1131         try {
1132             webDriverScreenshotHelper.screenshot(driver, this.getClass().getSimpleName(), testName.getMethodName(),
1133                     determinePage());
1134         } catch (Throwable t) {
1135             System.out.println("Problem with screenshot " + t.getMessage());
1136         }
1137     }
1138 
1139     protected void startSession(Method method) throws Exception {
1140         testMethodName = method.getName(); // TestNG
1141     }
1142 
1143     /**
1144      * Uses Selenium's findElements method which does not throw a test exception if not found.
1145      * @param by
1146      * @param selectText
1147      * @throws InterruptedException
1148      */
1149     protected void select(By by, String selectText) throws InterruptedException {
1150         //        checkForIncidentReport(by.toString(), "trying to select text " + selectText); // I think a report will now be picked-up by the jiraAwareFail
1151         WebElement select1 = findElement(by);
1152         WebDriverUtils.highlightElement(driver, select1);
1153         String name = select1.getAttribute("name");
1154         jGrowl("Select " + selectText + " from " + name);
1155         List<WebElement> options = select1.findElements(By.tagName("option"));
1156 
1157         for (WebElement option : options) {
1158             if (option.getText().equals(selectText)) {
1159                 option.click();
1160                 break; // continuing the loop after clicking on an option often causes cache problems other times it seems breaking here causes hangs?!
1161             }
1162         }
1163     }
1164 
1165     protected void selectByXpath(String locator, String selectText) throws InterruptedException {
1166         select(By.xpath(locator), selectText);
1167     }
1168 
1169     protected void selectByName(String name, String selectText) throws InterruptedException {
1170         select(By.name(name), selectText);
1171     }
1172 
1173     protected void selectChildWindow() {
1174         selectWindow(driver.getWindowHandles().toArray()[1].toString());
1175     }
1176 
1177     protected void selectParentWindow() {
1178         selectWindow(driver.getWindowHandles().toArray()[0].toString());
1179     }
1180 
1181     protected void selectTopFrame() {
1182         driver.switchTo().defaultContent();
1183     }
1184 
1185     protected void selectWindow(String locator) {
1186         driver.switchTo().window(locator);
1187     }
1188 
1189     /**
1190      * If a window contains the given title switchTo it.
1191      * @param title
1192      */
1193     public void switchToWindow(String title) {
1194         Set<String> windows = driver.getWindowHandles();
1195 
1196         for (String window : windows) {
1197             driver.switchTo().window(window);
1198             if (driver.getTitle().contains(title)) {
1199                 return;
1200             }
1201         }
1202     }
1203 
1204     /**
1205      * Tear down test as configured.  Do not allow exceptions to be thrown by tearDown, it kills the test run.
1206      * {@link WebDriverUtils#tearDown(boolean, String, String, String)}
1207      * {@link WebDriverUtils#REMOTE_PUBLIC_USERPOOL_PROPERTY}
1208      * {@link WebDriverUtils#dontTearDownPropertyNotSet()}
1209      * @throws Exception
1210      */
1211     @After
1212     public void tearDown() {
1213         try {
1214 
1215             if (!isPassed()) {
1216                 try { // if saucelabs has timed out getCurrentUrl throws an exception
1217                     System.out.println("Last AFT URL: " + driver.getCurrentUrl());
1218                 } catch (Throwable t) {
1219                     System.out.println("Unable to determine LAST AFT URL due to " + t.getMessage());
1220                 }
1221             }
1222 
1223             try { // saucelabs
1224                 if ((!isPassed() && webDriverScreenshotHelper.screenshotOnFailure()) || webDriverScreenshotHelper.screenshotSteps()) {
1225                     screenshot();
1226                 }
1227             } catch (Throwable t2) {
1228                 System.out.println("Unable to take failure screenshot " + t2.getMessage());
1229             }
1230 
1231             try { // saucelabs
1232                 if (isPassed() && WebDriverUtils.dontTearDownPropertyNotSet() && WebDriverUtils.dontTearDownOnFailure(isPassed())) {
1233                     logout();
1234                 }
1235             } catch (Throwable t3) {
1236                 System.out.println("Unable to logout " + t3.getMessage());
1237             }
1238 
1239             WebDriverUtils.tearDown(isPassed(), sessionId, this.toString().trim(), user, getClass().getSimpleName(), testName.getMethodName());
1240         } catch (Throwable t) {
1241             System.out.println("Exception in tearDown " + t.getMessage());
1242             t.printStackTrace();
1243         }
1244 
1245         // going to the login page and closing other windows so tests can be run in one browser
1246 //        acceptAlertIfPresent();
1247 //        closeAllOtherWindows(oneBrowserHandle);
1248 //        driver.get(getBaseUrlString()
1249 //                + "/kr-login/login?viewId=DummyLoginView&returnLocation=%2Fkr-krad%2Fkradsampleapp%3FviewId%3DKradSampleAppHome%26methodToCall%3Dstart");
1250 //        acceptAlertIfPresent();
1251 
1252         // comment out finally block for one browser
1253         finally {
1254             try {
1255                 closeAndQuitWebDriver();
1256             } catch (Throwable t) {
1257                 System.out.println(t.getMessage() + " occurred during tearDown, ignoring to avoid killing test run.");
1258                 t.printStackTrace();
1259                 System.out.println(t.getMessage() + " occurred during tearDown, ignoring to avoid killing test run.");
1260             }
1261         }
1262     }
1263 
1264     /**
1265      * Failures in testSetup cause the test to not be recorded.  Future plans are to extract form @Before and call at the start of each test.
1266      * Setup the WebDriver properties, test, and login.  Named testSetUp so it runs after TestNG's startSession(Method)
1267      * {@link WebDriverUtils#determineUser(String)}
1268      * {@link WebDriverUtils#setUp(String, String, String, String)}
1269      */
1270     @Before
1271     public void testSetUp() {
1272         // TODO it would be better if all opening of urls and logging in was not done in setUp, failures in setUp case the test to not be recorded. extract to setUp and call first for all tests.
1273         try { // Don't throw any exception from this methods, exceptions in Before annotations really mess up maven, surefire, or failsafe
1274             setUpSetUp();
1275 
1276             driver = WebDriverUtils.setUp(getClass().getSimpleName(), testMethodName); // one browser comment this out
1277 
1278             String testUrl = getTestUrl();
1279             // TODO Got into the situation where the first url doesn't expect server, but all others do.  Readdress once
1280             // the NavIT WDIT conversion has been completed.
1281             if (!testUrl.startsWith("http")) {
1282                 testUrl = getBaseUrlString() + testUrl;
1283             }
1284             WebDriverUtils.openTestUrl(driver, testUrl);
1285 
1286 //            oneBrowserHandle = driver.getWindowHandle(); // one browser other windows will be closed
1287 //            System.out.println("One Browser handle " + oneBrowserHandle);
1288 //            closeAllOtherWindows(oneBrowserHandle); // close all others than one browser
1289 
1290             this.sessionId = ((RemoteWebDriver) driver).getSessionId().toString();
1291             System.out.println(jGrowlHeader + " sessionId is " + sessionId);
1292 
1293 //            if (isVisible(By.name("login_user"))) { // one browser
1294                 login(driver, getUserName(), this);
1295 //            }
1296 
1297             navigateInternal(); // SeleniumBaseTest.fail from navigateInternal results in the test not being recorded as a failure in CI.
1298 
1299             javascriptErrorsReport();
1300 
1301         } catch (Throwable t) {
1302             System.out.println("Throwable " + t.getMessage() + " in Before annotated method is very bad, ignoring and letting first method of test class to fail.");
1303             t.printStackTrace();
1304             System.out.println("Throwable " + t.getMessage()
1305                     + " in Before annotated method is very bad, ignoring and letting first method of test class to fail.");
1306         }
1307     }
1308 
1309     public void setUpSetUp() {
1310         determineTestMethodName();
1311         determineImplicitWait();
1312         determineUser();
1313         determineJgrowlHeader();
1314     }
1315 
1316     protected void uncheck(By by) throws InterruptedException {
1317         WebElement element = findElement(by);
1318         if (element.isSelected()) {
1319             element.click();
1320         }
1321     }
1322 
1323     protected void uncheckByName(String name) throws InterruptedException {
1324         uncheck(By.name(name));
1325     }
1326 
1327     protected void uncheckByXpath(String locator) throws InterruptedException {
1328         uncheck(By.xpath(locator));
1329     }
1330 
1331     protected void waitAndClick(String locator) throws InterruptedException {
1332         waitAndClick(locator, this.getClass().toString());
1333     }
1334 
1335     protected void waitAndClick(By by) throws InterruptedException {
1336         jiraAwareWaitAndClick(by, this.getClass().toString());
1337     }
1338 
1339     protected void waitAndClick(By by, JiraAwareFailable failable) throws InterruptedException {
1340         jiraAwareWaitAndClick(by, this.getClass().toString(), failable);
1341     }
1342 
1343     protected void waitAndClick(String locator, String message) throws InterruptedException {
1344         jiraAwareWaitAndClick(By.cssSelector(locator), message);
1345     }
1346 
1347     protected void waitAndClickById(String id) throws InterruptedException {
1348         jiraAwareWaitAndClick(By.id(id), this.getClass().toString());
1349     }
1350 
1351     protected void waitAndClickById(String id, String message) throws InterruptedException {
1352         jiraAwareWaitAndClick(By.id(id), message);
1353     }
1354 
1355     protected void waitAndClickByLinkText(String text) throws InterruptedException {
1356         waitAndClickByLinkText(text, this.getClass().toString());
1357     }
1358 
1359     protected void waitAndClickByLinkText(String text, String message) throws InterruptedException {
1360         waitAndClickByLinkText(text, message, this);
1361     }
1362 
1363     protected void waitAndClickByLinkText(String text, JiraAwareFailable failable) throws InterruptedException {
1364         waitAndClickByLinkText(text, this.getClass().toString(), failable);
1365     }
1366 
1367     protected void waitAndClickByLinkText(String text, String message, JiraAwareFailable failable) throws InterruptedException {
1368         jGrowl("Click " + text + " link.");
1369         jiraAwareWaitAndClick(By.linkText(text), message, failable);
1370     }
1371 
1372     protected void waitAndClickLabeledLink(String label, String linkText) throws InterruptedException {
1373         jGrowl("Click link " + linkText + " labeled with " + label);
1374         waitAndClick(By.xpath(
1375                 "//th/label[contains(text(), '" + label + "')]/../following-sibling::*/div/span/a[contains(text(), '"
1376                         + linkText + "')]"));
1377     }
1378 
1379     protected void waitAndClickLabeledQuickFinder(String label) throws InterruptedException {
1380         jGrowl("Click link quickfinder labeled with " + label);
1381         waitAndClick(By.xpath("//th/label[contains(text(), '" + label
1382                 + "')]/../following-sibling::*/div/div/div/button[@class='btn btn-default uif-action icon-search']"));
1383         screenshot();
1384     }
1385 
1386     protected void waitAndTypeLabeledInput(String label, String text) throws InterruptedException {
1387         jGrowl("Type " + text + " in input labeled with " + label);
1388         waitAndTypeByXpath("//th/label[contains(text(), '" + label + "')]/../following-sibling::*//input", text);
1389         screenshot();
1390     }
1391 
1392     protected void waitAndSelectLabeled(String label, String text) throws InterruptedException {
1393         jGrowl("Select " + text + " labeled with " + label);
1394         waitAndSelectBy(By.xpath("//th/label[contains(text(), '" + label + "')]/../following-sibling::*//select"), text);
1395         screenshot();
1396     }
1397 
1398     protected void waitAndClickLightBoxClose() throws InterruptedException {
1399         jGrowl("Click lightbox close");
1400         waitAndClickByXpath("//button[contains(text(),'x')]");
1401     }
1402 
1403     protected void waitAndClickLinkContainingText(String linkText) throws InterruptedException {
1404         waitAndClickLinkContainingText(linkText, this.getClass().toString());
1405     }
1406 
1407     protected void waitAndClickLinkContainingText(String linkText, String message) throws InterruptedException {
1408         jGrowl("Click link containing " + linkText + " .");
1409         waitAndClickByXpath("//a[contains(text(), '" + linkText + "')]", message);
1410     }
1411 
1412     protected void waitAndClickByName(String name) throws InterruptedException {
1413         jGrowl("Click By Name " + name);
1414         jiraAwareWaitAndClick(By.name(name), this.getClass().toString());
1415     }
1416 
1417     protected void waitAndClickByValue(String value) throws InterruptedException {
1418         waitAndGetElementByAttributeValue("value", value).click();
1419     }
1420 
1421     protected void waitAndClickByXpath(String xpath) throws InterruptedException {
1422         waitAndClick(By.xpath(xpath));
1423     }
1424 
1425     protected void waitAndClickByXpath(String xpath, JiraAwareFailable failable) throws InterruptedException {
1426         waitAndClick(By.xpath(xpath), failable);
1427     }
1428 
1429     protected void waitAndClickByName(String name, String message) throws InterruptedException {
1430         jiraAwareWaitAndClick(By.name(name), message);
1431     }
1432 
1433     protected void waitAndClickByXpath(String xpath, String message) throws InterruptedException {
1434         jiraAwareWaitAndClick(By.xpath(xpath), message);
1435     }
1436 
1437     protected void waitAndClickByXpath(String xpath, int waitSeconds, String message) throws InterruptedException {
1438         jiraAwareWaitAndClick(By.xpath(xpath), waitSeconds, message, this);
1439     }
1440 
1441     protected void waitAndClickButtonByText(String buttonText) throws InterruptedException {
1442         waitAndClickButtonByText(buttonText, this.getClass().toString());
1443     }
1444 
1445     protected void waitAndClickButtonByText(String buttonText, int waitSeconds) throws InterruptedException {
1446         waitAndClickButtonByText(buttonText, waitSeconds, this.getClass().toString());
1447     }
1448 
1449     protected void waitAndClickButtonByText(String buttonText, String message) throws InterruptedException {
1450         jGrowl("Click " + buttonText + " button.");
1451         waitAndClickByXpath("//button[contains(text(), '" + buttonText + "')]", message);
1452     }
1453 
1454     protected void waitAndClickButtonByText(String buttonText, int waitSeconds, String message) throws InterruptedException {
1455         jGrowl("Click " + buttonText + " button.");
1456         waitAndClickByXpath("//button[contains(text(), '" + buttonText + "')]", waitSeconds, message);
1457     }
1458 
1459     protected void waitAndClickButtonByExactText(String buttonText) throws InterruptedException {
1460         waitAndClickButtonByExactText(buttonText, this.getClass().toString());
1461     }
1462 
1463     protected void waitAndClickButtonByExactText(String buttonText, String message) throws InterruptedException {
1464         jGrowl("Click " + buttonText + " button.");
1465         waitAndClickByXpath("//button[normalize-space(.)='" + buttonText + "']", message);
1466     }
1467 
1468     protected void waitAndClickAllByName(String name) throws InterruptedException{
1469         List<WebElement> elements = driver.findElements(By.name(name));
1470         for(WebElement ele : elements){
1471             ele.click();
1472         }
1473     }
1474     protected void waitAndClickConfirmCancelOk() throws InterruptedException {
1475         jGrowl("Click OK Confirmation");
1476         String xpath = "//div[@data-parent='ConfirmCancelDialog']/button[contains(text(),'OK')]";
1477         waitForElementVisibleBy(By.xpath(xpath)).click();
1478     }
1479 
1480     protected void waitAndClickConfirmBlanketApproveOk() throws InterruptedException {
1481         jGrowl("Click OK Confirmation");
1482         String xpath = "//div[@data-parent='ConfirmBlanketApproveDialog']/button[contains(text(),'OK')]";
1483         waitForElementVisibleBy(By.xpath(xpath)).click();
1484     }
1485 
1486     protected void waitAndClickConfirmDeleteYes() throws InterruptedException {
1487         jGrowl("Click Yes Confirmation");
1488         String xpath = "//section[@id='DialogGroup-DeleteFileUploadLine']//button[contains(text(),'Yes')]";
1489         waitForElementVisibleBy(By.xpath(xpath)).click();
1490     }
1491 
1492     protected void waitAndClickConfirmSaveOnClose() throws InterruptedException {
1493         jGrowl("Click OK Confirmation");
1494         waitForElementVisibleBy(By.xpath("//div[@data-parent='ConfirmSaveOnCloseDialog']/button[contains(text(),'Yes')]"));
1495         waitAndClickByXpath("//div[@data-parent='ConfirmSaveOnCloseDialog']/button[contains(text(),'Yes')]");
1496     }
1497 
1498     protected void waitAndClickCancelSaveOnClose() throws InterruptedException {
1499         jGrowl("Click OK Confirmation");
1500         waitForElementVisibleBy(By.xpath(
1501                 "//div[@data-parent='ConfirmSaveOnCloseDialog']/button[contains(text(),'No')]"));
1502         waitAndClickByXpath("//div[@data-parent='ConfirmSaveOnCloseDialog']/button[contains(text(),'No')]");
1503     }
1504 
1505 
1506     protected void waitAndClickConfirmSubmitOk() throws InterruptedException {
1507         jGrowl("Click OK Confirmation");
1508         String xpath = "//div[@data-parent='ConfirmSubmitDialog']/button[contains(text(),'OK')]";
1509         waitForElementVisibleBy(By.xpath(xpath)).click();
1510     }
1511 
1512     protected void waitAndClickDropDown(String dropDownText) throws InterruptedException {
1513         jGrowl("Click the " + dropDownText + " drop down.");
1514         WebElement dropdownMenu = waitAndGetElementByAttributeValue("class", "dropdown-toggle");
1515         Thread.sleep(1000);
1516         dropdownMenu.click();
1517         waitAndClickByLinkText(dropDownText, "dropdown click " + dropDownText + " problem");
1518     }
1519 
1520     protected void waitAndClickReturnValue() throws InterruptedException {
1521         waitAndClickByLinkText(RETURN_VALUE_LINK_TEXT, "Unable to click return value " + this.getClass().toString());
1522     }
1523 
1524     protected void waitAndClickReturnValue(String message) throws InterruptedException {
1525         waitAndClickByLinkText(RETURN_VALUE_LINK_TEXT, message);
1526     }
1527 
1528     protected void waitAndClickSearch3() throws InterruptedException {
1529         jGrowl("Click Search");
1530         waitAndClickByXpath(SEARCH_XPATH_3);
1531     }
1532 
1533     protected String waitAndGetAttribute(By by, String attribute) throws InterruptedException {
1534         jiraAwareWaitFor(by, attribute);
1535 
1536         return findElement(by).getAttribute(attribute);
1537     }
1538 
1539     /**
1540      * Get value of any attribute by using element name
1541      *
1542      * @param name name of an element
1543      * @param attribute the name of an attribute whose value is to be retrieved
1544      */
1545     protected String waitAndGetAttributeByName(String name, String attribute) throws InterruptedException {
1546         return waitAndGetAttribute(By.name(name), attribute);
1547     }
1548 
1549     /**
1550      * Get value of any attribute by using element xpath
1551      *
1552      * @param locator locating mechanism of an element
1553      * @param attribute the name of an attribute whose value is to be retrieved
1554      */
1555     protected String waitAndGetAttributeByXpath(String locator, String attribute) throws InterruptedException {
1556         return waitAndGetAttribute(By.xpath(locator), attribute);
1557     }
1558 
1559     protected WebElement waitAndGetElementByAttributeValue(String attribute, String attributeValue) throws InterruptedException {
1560         return WebDriverUtils.waitAndGetElementByAttributeValue(driver, attribute, attributeValue, waitSeconds);
1561     }
1562 
1563     protected List<WebElement> waitAndGetElementsByAttributeValue(String attribute, String attributeValue) throws InterruptedException {
1564         // jenkins implies that implicitlyWait is worse than sleep loop for finding elements by 100+ test failures on the old sampleapp
1565         //        driver.manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
1566         //        driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
1567 
1568         driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
1569 
1570         boolean failed = false;
1571 
1572         for (int second = 0;; second++) {
1573             Thread.sleep(1000);
1574             if (second >= waitSeconds)
1575                 failed = true;
1576             try {
1577                 if (failed || (getElementsByAttributeValue(attribute, attributeValue) != null)) {
1578                     break;
1579                 }
1580             } catch (Exception e) {}
1581         }
1582 
1583         List<WebElement> elements = getElementsByAttributeValue(attribute, attributeValue);
1584         driver.manage().timeouts().implicitlyWait(WebDriverUtils.configuredImplicityWait(), TimeUnit.SECONDS);
1585         return elements;
1586     }
1587 
1588     protected String waitAndGetLabeledText(String label) throws InterruptedException {
1589         return waitForElementPresent(By.xpath("//th/label[contains(text(), '"
1590                 + label
1591                 + "')]/../following-sibling::*/div/span")).getText();
1592     }
1593 
1594     protected String[] waitAndGetText(By by) throws InterruptedException {
1595         WebDriverUtils.waitFors(driver, WebDriverUtils.configuredImplicityWait(), by, this.getClass().toString());
1596         List<WebElement> found = findElements(by);
1597         String[] texts = new String[found.size()];
1598         int i = 0;
1599 
1600         for (WebElement element: found) {
1601             texts[i++] = element.getText();
1602         }
1603 
1604         if (texts.length == 0) {
1605             jiraAwareFail(by.toString());
1606         }
1607 
1608         return texts;
1609     }
1610 
1611 
1612     protected void waitAndSelectBy(By by, String selectText) throws InterruptedException {
1613         waitFor(by, selectText + " not found.");
1614         select(by, selectText);
1615     }
1616 
1617     protected void waitAndSelectByName(String name, String selectText) throws InterruptedException {
1618         waitAndSelectBy(By.name(name), selectText);
1619     }
1620 
1621     protected WebElement waitAndType(By by, String text) throws InterruptedException {
1622         return waitAndType(by, text, this.getClass().toString());
1623     }
1624 
1625     protected WebElement waitAndType(String selector, String text) throws InterruptedException {
1626         return waitAndType(By.cssSelector(selector), text);
1627     }
1628 
1629     protected WebElement waitAndTypeById(String id, String text) throws InterruptedException {
1630         return waitAndType(By.id(id), text);
1631     }
1632 
1633     protected WebElement waitAndTypeByXpath(String locator, String text) throws InterruptedException {
1634         return waitAndType(By.xpath(locator), text);
1635     }
1636 
1637     protected WebElement waitAndTypeByXpath(String locator, String text, String message) throws InterruptedException {
1638         return waitAndType(By.xpath(locator), text, message);
1639     }
1640 
1641     protected WebElement waitAndTypeByName(String name, String text) throws InterruptedException {
1642         return waitAndType(By.name(name), text);
1643     }
1644 
1645     protected boolean waitAreAnyVisible(By[] bys) throws InterruptedException {
1646         if (bys == null || bys.length == 0 ) {
1647             return false;
1648         }
1649 
1650         for (int second = 0; second < waitSeconds; second++) {
1651 
1652             if (isVisible(bys)) {
1653                 return true;
1654             }
1655 
1656             Thread.sleep(1000);
1657         }
1658 
1659         return false;
1660     }
1661 
1662     /**
1663      * {@deprecated} use any of the various wait methods over this, waitForElementPresent for example.
1664      * @throws InterruptedException
1665      */
1666     protected void waitForPageToLoad() throws InterruptedException {
1667         Thread.sleep(5000);
1668         checkForIncidentReport();
1669     }
1670 
1671     protected WebElement waitFor(By by) throws InterruptedException {
1672         return jiraAwareWaitFor(by, this.getClass().toString());
1673     }
1674 
1675     /**
1676      * Should be called from jiraAwareWaitFor to get KULRICE error output in CI.
1677      *
1678      * Inner most waitFor, let it throw the failure so the timeout message reflects the waitSeconds time, not the 1
1679      * second it is set to before returning.
1680      * @param by
1681      * @param message
1682      * @throws InterruptedException
1683      */
1684     protected void waitFor(By by, String message) throws InterruptedException {
1685         WebDriverUtils.waitFor(this.driver, this.waitSeconds, by, message);
1686     }
1687 
1688     /**
1689      * Uses Selenium's findElements method which does not throw a test exception if not found.
1690      * @param elementLocator
1691      * @param message
1692      * @throws InterruptedException
1693      */
1694     protected WebElement waitForElementVisible(String elementLocator, String message) throws InterruptedException {
1695         return waitForElementVisibleBy(By.cssSelector(elementLocator), message);
1696     }
1697 
1698     protected WebElement waitForElementVisibleBy(By by) throws InterruptedException {
1699         return waitForElementVisibleBy(by, by.toString() + " NOT visible for class " + this.getClass().getSimpleName());
1700     }
1701 
1702     protected WebElement waitForElementVisibleBy(By by, String message) throws InterruptedException {
1703         driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
1704 
1705         boolean failed = false;
1706 
1707         for (int second = 0;; second++) {
1708             if (second >= waitSeconds)
1709                 failed = true;
1710             try {
1711                 if (failed || driver.findElement(by).isDisplayed())
1712                     break;
1713             } catch (Exception e) {}
1714             Thread.sleep(1000);
1715         }
1716 
1717         checkForIncidentReport(by.toString()); // after timeout to be sure page is loaded
1718 
1719         driver.manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
1720 
1721         if (failed) {
1722             jiraAwareFail("timeout of " + waitSeconds + " seconds waiting for " + by + " " + message + " " + driver
1723                     .getCurrentUrl());
1724             return null;
1725         }
1726         return driver.findElements(by).get(0);
1727     }
1728 
1729     protected void waitForElementVisibleById(String id, String message) throws InterruptedException {
1730         waitForElementVisibleBy(By.id(id), message);
1731     }
1732 
1733     protected WebElement waitForElementPresent(By by) throws InterruptedException {
1734         return jiraAwareWaitFor(by, this.getClass().toString());
1735     }
1736 
1737     protected WebElement waitForElementPresent(By by, String message) throws InterruptedException {
1738         return jiraAwareWaitFor(by, message);
1739     }
1740 
1741     protected WebElement waitForElementPresent(String locator) throws InterruptedException {
1742         return jiraAwareWaitFor(By.cssSelector(locator), this.getClass().toString());
1743     }
1744 
1745     protected WebElement waitForElementPresentByClassName(String name) throws InterruptedException {
1746         return jiraAwareWaitFor(By.className(name), this.getClass().toString());
1747     }
1748 
1749     protected WebElement waitForElementPresentByClassName(String name, String message) throws InterruptedException {
1750         return jiraAwareWaitFor(By.className(name), message);
1751     }
1752 
1753     protected WebElement waitForElementPresentByClassName(String name, int seconds) throws InterruptedException {
1754         return jiraAwareWaitFor(By.className(name), seconds, this.getClass().toString());
1755     }
1756 
1757     protected void waitForElementsPresentByClassName(String name, String message) throws InterruptedException {
1758         jiraAwareWaitFors(By.className(name), message);
1759     }
1760 
1761     protected String waitForLabeledText(String label) throws InterruptedException {
1762         return waitForElementVisibleBy(By.xpath("//th/label[contains(text(), '"
1763                 + label
1764                 + "')]/../following-sibling::*/div/span")).getText();
1765     }
1766 
1767     /**
1768      * {@see WebDriverUtils#waitFor}.
1769      *
1770      * @param by to find
1771      * @param message on failure
1772      */
1773     protected List<WebElement> waitAndGetElementsFor(By by, String message) throws InterruptedException {
1774         try {
1775             return WebDriverUtils.waitFors(getDriver(), WebDriverUtils.configuredImplicityWait(), by, message);
1776         } catch (Throwable t) {
1777             jiraAwareFail(by, message, t);
1778         }
1779         return new ArrayList<WebElement>();
1780     }
1781 
1782     protected WebElement waitForElementPresentById(String id) throws InterruptedException {
1783         return jiraAwareWaitFor(By.id(id), this.getClass().toString());
1784     }
1785 
1786     protected void waitForElementPresentById(String id, String message) throws InterruptedException {
1787         jiraAwareWaitFor(By.id(id), message);
1788     }
1789 
1790     protected void waitForElementPresentById(String id, String message, int seconds) throws InterruptedException {
1791         jiraAwareWaitFor(By.id(id), seconds, message);
1792     }
1793 
1794     protected void waitForElementsPresentById(String id, String message) throws InterruptedException {
1795         jiraAwareWaitFors(By.id(id), message);
1796     }
1797 
1798     protected WebElement waitForElementPresentByName(String name) throws InterruptedException {
1799         return waitForElementPresentByName(name, this.getClass().toString());
1800     }
1801 
1802     protected WebElement waitForElementPresentByName(String name, String message) throws InterruptedException {
1803         return jiraAwareWaitFor(By.name(name), message);
1804     }
1805 
1806     protected WebElement waitForElementPresentByXpath(String xpath) throws InterruptedException {
1807         return jiraAwareWaitFor(By.xpath(xpath), this.getClass().toString());
1808     }
1809 
1810     protected WebElement waitForElementPresentByXpath(String xpath, String message) throws InterruptedException {
1811         return jiraAwareWaitFor(By.xpath(xpath), message);
1812     }
1813 
1814     protected void waitForElementsPresentByXpath(String xpathLocator) throws InterruptedException {
1815         jiraAwareWaitFors(By.xpath(xpathLocator), this.getClass().toString());
1816     }
1817 
1818     protected void waitForElementNotPresent(By by) throws InterruptedException {
1819         waitForElementNotPresent(by, WebDriverUtils.configuredImplicityWait());
1820     }
1821 
1822     protected void waitForElementNotPresent(By by, int secondsToWait) throws InterruptedException {
1823         waitForElementNotPresent(by, this.getClass().getSimpleName(), secondsToWait);
1824     }
1825 
1826     protected void waitForElementNotPresent(By by, String message) throws InterruptedException {
1827         waitForElementNotPresent(by, this.getClass().getSimpleName(), WebDriverUtils.configuredImplicityWait());
1828     }
1829 
1830     protected void waitForElementNotPresent(By by, String message, int secondsToWait) throws InterruptedException {
1831         driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
1832         while (isElementPresent(by)) {
1833             if (secondsToWait == 0) {
1834                 break;
1835             }
1836             secondsToWait -= 1;
1837             Thread.sleep(1000);
1838         }
1839         if (isElementPresent(by)) {
1840             jiraAwareFail(by + " is still present " + message);
1841         }
1842         driver.manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
1843     }
1844 
1845 
1846     protected boolean waitForIsTextPresent(String text) throws InterruptedException {
1847         boolean present = false;
1848         driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
1849         int secondsToWait = WebDriverUtils.configuredImplicityWait();
1850         while (!isTextPresent(text) && secondsToWait > 0) {
1851             secondsToWait -= 1;
1852             Thread.sleep(1000);
1853         }
1854         if (isTextPresent(text)) {
1855             present = true;
1856         }
1857         driver.manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
1858         return present;
1859     }
1860 
1861     protected void waitForProgress(String altText) throws InterruptedException {
1862         waitForProgress(altText, waitSeconds);
1863     }
1864 
1865     protected void waitForProgress(String altText, int timeout) throws InterruptedException {
1866         driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
1867         for (int second = 0;; second++) {
1868             Thread.sleep(1000); // sleep for a second first, give element time to exist
1869 
1870             if (second >= timeout) {
1871                 jiraAwareFail(TIMEOUT_MESSAGE + " still Loading after " + timeout + " seconds.");
1872             }
1873 
1874             try {
1875                 if (!isElementPresentByXpath("//img[@alt='" + altText + "']") || !isVisible(By.xpath("//img[@alt='" + altText + "']"))) {
1876                     break;
1877                 }
1878             } catch (Exception e) {
1879                 // assume timing with img going away and continue with test
1880                 break;
1881             }
1882 
1883         }
1884         driver.manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
1885     }
1886 
1887     protected void waitForProgressAddingLine() throws InterruptedException {
1888         waitForProgress("Adding Line...");
1889     }
1890 
1891     protected void waitForProgressDeletingLine() throws InterruptedException {
1892         waitForProgress("Deleting Line...");
1893     }
1894 
1895     protected void waitForProgressAddingLine(int secondsToWait) throws InterruptedException {
1896         waitForProgress("Adding Line...", secondsToWait);
1897     }
1898 
1899     protected void waitForProgressLoading() throws InterruptedException {
1900         waitForProgress("Loading...", WebDriverUtils.configuredImplicityWait() * 4);
1901     }
1902 
1903     protected void waitForProgressLoading(int secondsToWait) throws InterruptedException {
1904         waitForProgress("Loading...", secondsToWait);
1905     }
1906 
1907     protected void waitForProgressSaving() throws InterruptedException {
1908         waitForProgress("Saving...", WebDriverUtils.configuredImplicityWait() * 4);
1909     }
1910 
1911     protected void waitForProgressSaving(int secondsToWait) throws InterruptedException {
1912         waitForProgress("Saving...", secondsToWait);
1913     }
1914 
1915     protected void waitForTextPresent(String text) throws InterruptedException {
1916         waitForTextPresent(text, WebDriverUtils.configuredImplicityWait());
1917     }
1918 
1919     protected void waitForTextPresent(String text, String message) throws InterruptedException {
1920         waitForTextPresent(text, WebDriverUtils.configuredImplicityWait(), message);
1921     }
1922 
1923     protected void waitForTextPresent(String text, int secondsToWait) throws InterruptedException {
1924         waitForTextPresent(text, secondsToWait, this.getClass().getSimpleName());
1925     }
1926 
1927     protected void waitForTextPresent(String text, int secondsToWait, String message) throws InterruptedException {
1928         driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
1929         while (!isTextPresent(text) && secondsToWait > 0) {
1930             secondsToWait -= 1;
1931             Thread.sleep(1000);
1932         }
1933         if (!isTextPresent(text)) {
1934             jiraAwareFail(message + " " + text + " is not present for " + this.getClass().toString());
1935         }
1936         driver.manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
1937     }
1938 
1939     protected void waitForTextNotPresent(String text) throws InterruptedException {
1940         driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
1941         int secondsToWait = WebDriverUtils.configuredImplicityWait();
1942         while (isTextPresent(text) && secondsToWait > 0) {
1943             secondsToWait -= 1;
1944             Thread.sleep(1000);
1945         }
1946         if (isTextPresent(text)) {
1947             jiraAwareFail(text + " is still present for " + this.getClass().toString());
1948         }
1949         driver.manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
1950     }
1951 
1952     protected void waitIsVisible(By by) throws InterruptedException {
1953         waitIsVisible(by, this.getClass().getSimpleName());
1954     }
1955 
1956     protected void waitIsVisible(By by, String message) throws InterruptedException {
1957         for (int second = 0;; second++) {
1958             if (second >= waitSeconds) {
1959                 jiraAwareFail(TIMEOUT_MESSAGE + " " + by.toString() + " " + message);
1960             }
1961             if (isVisible(by)) {
1962                 break;
1963             }
1964             Thread.sleep(1000);
1965         }
1966 
1967         if (!isVisible(by)) {
1968             jiraAwareFail(by.toString() + " not visiable", message);
1969         }
1970     }
1971 
1972     protected void waitIsVisible(String locator) throws InterruptedException {
1973         waitIsVisible(By.cssSelector(locator));
1974     }
1975 
1976     protected void waitIsVisibleByXpath(String locator) throws InterruptedException {
1977         waitIsVisible(By.xpath(locator));
1978     }
1979 
1980     protected void waitIsVisibleByXpath(String locator, String message) throws InterruptedException {
1981         waitIsVisible(By.xpath(locator), message);
1982     }
1983 
1984     protected void waitNotVisible(By by) throws InterruptedException {
1985         waitNotVisible(by, this.getClass().getSimpleName());
1986     }
1987 
1988     protected void waitNotVisible(By by, String message) throws InterruptedException {
1989         for (int second = 0;; second++) {
1990             if (second >= waitSeconds) {
1991                 jiraAwareFail(TIMEOUT_MESSAGE + " " + message);
1992             }
1993             if (!isVisible(by)) {
1994                 break;
1995             }
1996             Thread.sleep(1000);
1997         }
1998     }
1999 
2000     protected void waitNotVisibleByXpath(String locator) throws InterruptedException {
2001         waitNotVisible(By.xpath(locator));
2002     }
2003 
2004     protected void waitNotVisibleByXpath(String locator, String message) throws InterruptedException {
2005         waitNotVisible(By.xpath(locator), message);
2006     }
2007 }