View Javadoc
1   /**
2    * Copyright 2005-2014 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.Assert;
19  import org.kuali.rice.testtools.common.JiraAwareFailable;
20  import org.kuali.rice.testtools.common.JiraAwareFailureUtils;
21  import org.openqa.selenium.By;
22  import org.openqa.selenium.WebDriver;
23  import org.openqa.selenium.WebElement;
24  
25  import java.util.List;
26  
27  /**
28   * <p>
29   * Jira Aware Automated Functional Test Base.
30   * </p><p>
31   * <ul>
32   *     <li>{@see JiraAwareWebDriverUtils}</li>
33   *     <li>{@see JiraAwareFailable}</li>
34   *     <li>{@see JiraAwareFailure}</li>
35   * </ul>
36   * TODO: promote the various jiraAware methods from WebDriverLegacyITBase
37   * </p>
38   *
39   * @author Kuali Rice Team (rice.collab@kuali.org)
40   */
41  public abstract class JiraAwareAftBase extends AutomatedFunctionalTestBase implements JiraAwareFailable {
42  
43      /**
44       * Test state, used for Saucelabs REST API call to set test state via @{see SauceLabsWebDriverHelper#tearDown}.
45       */
46      private boolean passed = false;
47  
48      /**
49       * Implement to check for Incident Report or other on screen errors, should call {@see JiraAwareFailable#fail} to fail,
50       * without calling any of the jiraAwareFail methods to avoid an infinite loop.
51       *
52       * @param locator used in failure message if there is an incident report can be blank
53       * @param message used in failure message if there is an incident report can be blank
54       */
55      protected abstract void checkForIncidentReport(String locator, String message);
56  
57      /**
58       * WebDriver used in fail and pass to display jGrowl messages.
59       *
60       * @return WebDriver used to display jGrowl messages on fail and pass
61       */
62      protected abstract WebDriver getDriver();
63  
64      /**
65       * {@see WebDriverUtils#assertButtonDisabledByText}
66       *
67       * @param buttonText of button to assert is disabled
68       */
69      protected void assertButtonDisabledByText(String buttonText) {
70          JiraAwareWebDriverUtils.assertButtonDisabledByText(getDriver(), buttonText, this);
71      }
72  
73      /**
74       * {@see WebDriverUtils.assertButtonEnabledByText}.
75       *
76       * @param buttonText of button to assert is disabled
77       */
78      protected void assertButtonEnabledByText(String buttonText) {
79          JiraAwareWebDriverUtils.assertButtonEnabledByText(getDriver(), buttonText, this);
80      }
81  
82      protected void assertDataTableContains(String[][] data) throws InterruptedException {
83          boolean dataPresent = true;
84          String missingMessage = "";
85          String dataTableRow;
86          for (int i = 0, s = data.length; i < s; i++) {
87              dataTableRow = findDataTableRow(data[i][0]).getText();
88              for (int j = 1, t = data[i].length; j < t; j++) {
89                  if (!dataTableRow.contains(data[i][j])) {
90                      dataPresent = false;
91                      missingMessage += data[i][j] + " not present in data table row containing " + data[i][0] + ". ";
92                  }
93              }
94              WebDriverUtils.jGrowl(getDriver(), "Assert DataTable Row", false, "Assert datatable row '" + dataTableRow
95                      + "' contains '" + data[i] + "' " + dataPresent);
96          }
97          if (!dataPresent) {
98              jiraAwareFail(missingMessage);
99          }
100     }
101 
102     protected void assertDataTableContains(String[][] data, String tableClass) throws InterruptedException {
103         boolean dataPresent = true;
104         String missingMessage = "";
105         String dataTableRow;
106         for (int i = 0, s = data.length; i < s; i++) {
107             dataTableRow = findDataTableRow(data[i][0], tableClass).getText();
108             for (int j = 1, t = data[i].length; j < t; j++) {
109                 if (!dataTableRow.contains(data[i][j])) {
110                     dataPresent = false;
111                     missingMessage += data[i][j] + " not present in data table row containing " + data[i][0] + ". ";
112                 }
113             }
114         }
115         if (!dataPresent) {
116             jiraAwareFail(missingMessage);
117         }
118     }
119 
120     protected void assertElementPresentByName(String name) {
121         assertElementPresentByName(name, this.getClass().toString());
122     }
123 
124     protected void assertElementPresentByName(String name, String message) {
125         try {
126             findElement(By.name(name));
127         } catch (Throwable t) {
128             jiraAwareFail(name + " not present " + message);
129         }
130     }
131 
132     protected void assertElementPresentByXpath(String locator) {
133         assertElementPresentByXpath(locator, this.getClass().toString());
134     }
135 
136     protected void assertElementPresent(By by) {
137         assertElementPresent(by, this.getClass().toString());
138     }
139 
140     protected void assertElementPresent(By by, String message) {
141         try {
142             findElement(by);
143         } catch (Throwable t) {
144             jiraAwareFail(by, message, t);
145         }
146     }
147 
148     protected void assertElementPresentByXpath(String locator, String message) {
149         try {
150             findElement(By.xpath(locator));
151         } catch (Throwable t) {
152             jiraAwareFail(By.xpath(locator), message, t);
153         }
154     }
155 
156     protected void assertElementPresentByLinkText(String linkText) {
157         try {
158             findElement(By.linkText(linkText));
159         } catch (Throwable t) {
160             jiraAwareFail(By.cssSelector(linkText), this.getClass().toString(), t);
161         }
162 
163     }
164 
165     protected void assertElementPresent(String locator) {
166         try {
167             findElement(By.cssSelector(locator));
168         } catch (Throwable t) {
169             jiraAwareFail(By.cssSelector(locator), this.getClass().toString(), t);
170         }
171     }
172 
173     protected void assertEquals(boolean expected, boolean actual) {
174         if (expected != actual) {
175             jiraAwareFail("Expected \"" + expected + "\" but saw \"" + actual + "\" instead");
176         }
177     }
178 
179     protected void assertEquals(int expected, int actual) {
180         if (expected != actual) {
181             jiraAwareFail("Expected \"" + expected + "\" but saw \"" + actual + "\" instead");
182         }
183     }
184 
185     protected void assertEquals(String message, int expected, int actual) {
186         if (expected != actual) {
187             jiraAwareFail("Expected \"" + expected + "\" but saw \"" + actual + "\" instead " + message);
188         }
189     }
190 
191 
192     protected void assertEquals(String expected, String actual) {
193         if (!expected.equals(actual)) {
194             jiraAwareFail("Expected \"" + expected + "\" but saw \"" + actual + "\" instead in " + getClass().toString());
195         }
196     }
197 
198     protected void assertEquals(String message, String expected, String actual) {
199         if (!expected.equals(actual)) {
200             jiraAwareFail("Expected \"" + expected + "\" but saw \"" + actual + "\" instead " + message);
201         }
202     }
203 
204     /**
205      * If booleanToAssertFalse is true call {@see jiraAwareFail}.
206      *
207      * @param booleanToAssertFalse
208      */
209     protected void assertFalse(boolean booleanToAssertFalse) {
210         JiraAwareWebDriverUtils.assertFalse(booleanToAssertFalse, this);
211     }
212 
213     /**
214      * If booleanToAssertFalse is true call {@see jiraAwareFail}.
215      *
216      * @param message to include if booleanToAssertTrue is true
217      * @param booleanToAssertFalse
218      */
219     protected void assertFalse(String message, boolean booleanToAssertFalse) {
220         JiraAwareWebDriverUtils.assertFalse(message, booleanToAssertFalse, this);
221     }
222 
223     protected void assertIsVisible(String locator) {
224         if (!isVisible(locator)) {
225             jiraAwareFail(locator + " is not visible and should be");
226         }
227     }
228 
229     protected void assertIsVisible(By by, String message) {
230         if (!isVisible(by)) {
231             jiraAwareFail(by + " not visible " + message);
232         }
233     }
234 
235     protected void assertIsVisibleById(String id) {
236         if (!isVisibleById(id)) {
237             jiraAwareFail(id + " is not visible and should be");
238         }
239     }
240 
241     protected void assertIsVisibleByXpath(String xpath, String message) {
242         if (!isVisibleByXpath(xpath)) {
243             jiraAwareFail(xpath + " not visible " + message);
244         }
245     }
246 
247     protected void assertIsNotVisible(By by) {
248         assertIsNotVisible(by, this.getClass().toString());
249     }
250 
251     protected void assertIsNotVisible(By by, String message) {
252         if (isVisible(by)) {
253             jiraAwareFail(by + " is visible and should not be " + message);
254         }
255     }
256 
257     protected void assertIsNotVisible(String locator) {
258         if (isVisible(locator)) {
259             jiraAwareFail(locator + " is visible and should not be");
260         }
261     }
262 
263     protected void assertIsNotVisibleByXpath(String xpath) {
264         if (isVisible(By.xpath(xpath))) {
265             jiraAwareFail(xpath + " is visible and should not be");
266         }
267     }
268 
269     protected void assertIsNotVisibleByXpath(String xpath, String message) {
270         if (isVisibleByXpath(xpath)) {
271             jiraAwareFail(xpath + " visible and should not be " + message);
272         }
273     }
274 
275     protected void assertLabeledTextNotPresent(String[][] labeledText) {
276         boolean allLabeledTextNotPresent = true;
277         String missingMessage = "";
278         for (int i = 0, s = labeledText.length; i < s; i++) {
279             if (isLabeledTextPresent(labeledText[i][0], labeledText[i][1])) {
280                 allLabeledTextNotPresent = false;
281                 missingMessage += "Text: " + labeledText[i][1] + " labeled by: " + labeledText[i][0] + " present. ";
282             }
283         }
284         if (!allLabeledTextNotPresent) {
285             jiraAwareFail(missingMessage);
286         }
287     }
288 
289     protected void assertLabeledTextPresent(String[][] labeledText) {
290         boolean allLabeledTextPresent = true;
291         String missingMessage = "";
292         for (int i = 0, s = labeledText.length; i < s; i++) {
293             if (!isLabeledTextPresent(labeledText[i][0], labeledText[i][1])) {
294                 allLabeledTextPresent = false;
295                 missingMessage += "Text: " + labeledText[i][1] + " labeled by: " + labeledText[i][0] + " not present. ";
296             }
297         }
298         if (!allLabeledTextPresent) {
299             jiraAwareFail(missingMessage);
300         }
301     }
302 
303     protected void assertLabeledTextPresent(String label, String text) {
304         if (!isLabeledTextPresent(label, text)) {
305             jiraAwareFail("Text: " + text + " labeled by: " + label + " not present");
306         }
307     }
308 
309     protected void assertResultCount(String count) throws InterruptedException {
310         jiraAwareWaitFor(By.cssSelector("div.dataTables_info"), "result count for " + this.getClass().toString());
311         assertTextPresent("of " + count + " entries", "div.dataTables_info", this.getClass().toString());
312     }
313 
314     /**
315      * <b>WARNING:</b> this only does a check against the page source.  The form url can have random character that match
316      * simple text.  A narrowly scoped locator for {@see #assertTextPresent(String String String)}
317      *
318      * @param text
319      */
320     protected void assertTextPresent(String text) {
321         assertTextPresent(text, this.getClass().toString());
322     }
323 
324     /**
325      * <b>WARNING:</b> this only does a check against the page source.  The form url can have random character that match simple text
326      * @param text
327      */
328     protected void assertTextPresent(String text, String message) {
329         WebDriverUtils.jGrowl(getDriver(), "Assert Text Present", false, "Assert text '" + text + "' is present.");
330         String pageSource = getDriver().getPageSource();
331         if (!pageSource.contains(text)) {
332             jiraAwareFail(text + " not present " + message);
333         }
334         WebDriverUtils.highlightElement(getDriver(), By.xpath("//*[contains(text(), '" + text + "')]"));
335     }
336 
337     /**
338      * @param text
339      */
340     protected void assertTextPresent(String text, String cssSelector, String message){
341         WebElement element = findElement(By.cssSelector(cssSelector));
342         if (!element.getText().contains(text)){
343             jiraAwareFail(text + " for " + cssSelector + " not present " + message);
344         }
345     }
346 
347     /**
348      * Asset that the given text does not occur in the page
349      * Warning, this only does a check against the page source.  The form url can have random character that match simple text
350      * @param text the text to search for
351      */
352     protected void assertTextNotPresent(String text) {
353         assertTextNotPresent(text, this.getClass().toString());
354     }
355 
356     /**
357      * Assert that the given text does not occur in the page, and add an additional message to the failure
358      * @param text the text to search for
359      * @param message the message to add to the failure
360      */
361     protected void assertTextNotPresent(String text, String message) {
362         String contents = getDriver().getPageSource();
363         if (contents.contains(text)) {
364             jiraAwareFail(text + " is present and should not be " + message);
365         }
366     }
367 
368     /**
369      * @param text
370      */
371     protected void assertTextNotPresent(String text, String cssSelector, String message){
372         WebElement element = findElement(By.cssSelector(cssSelector));
373         if (element.getText().contains(text)){
374             jiraAwareFail(text + " for " + cssSelector + " is present and shouldn't be " + message);
375         }
376     }
377 
378     /**
379      * If booleanToAssertTrue is false call {@see jiraAwareFail}.
380      *
381      * @param booleanToAssertTrue
382      */
383     protected void assertTrue(boolean booleanToAssertTrue) {
384         JiraAwareWebDriverUtils.assertTrue(getClass().toString(), booleanToAssertTrue, this);
385     }
386 
387     /**
388      * If booleanToAssertTrue is false call {@see jiraAwareFail}.
389      *
390      * @param message to include if booleanToAssertTrue is false
391      * @param booleanToAssertTrue
392      */
393     protected void assertTrue(String message, boolean booleanToAssertTrue) {
394         JiraAwareWebDriverUtils.assertTrue(message, booleanToAssertTrue, this);
395     }
396 
397     /**
398      * {@inheritDoc}
399      * <p>
400      * Set passed to false, call jGrowl sticky with the given message, then fails using  {@see JiraAwareFailable#fail}.
401      * </p>
402      * @param message to display with failure
403      */
404     @Override
405     public void fail(String message) {
406         passed = false;
407         WebDriverUtils.jGrowl(getDriver(), "Failure " + getClass().getSimpleName(), true, message);
408         Assert.fail(message); // The final fail that JiraAwareFailure calls, do not change this to a JiraAwareFailure.
409     }
410 
411     protected WebElement findDataTableRow(String keyText) throws InterruptedException {
412         return findDataTableRow(keyText, "dataTable");
413     }
414 
415     protected WebElement findDataTableRow(String keyText, String className) throws InterruptedException {
416         jiraAwareWaitFor(By.className(className));
417         WebElement element = findElement(By.className(className));
418         return findElement(By.xpath("./*/tr//*[contains(text(), '" + keyText + "')]/ancestor::tr"), element);
419     }
420 
421     /**
422      * {@see WebDriverUtils#findElement}.
423      *
424      * @param by to find element with
425      * @return WebElement found with given by
426      */
427     protected WebElement findElement(By by) {
428         try {
429             return WebDriverUtils.findElement(getDriver(), by);
430         } catch (Throwable t) {
431             jiraAwareFail(by.toString(), t.getMessage(), t);
432         }
433         return null; // required by compiler, never reached
434     }
435 
436     protected WebElement findElement(By by, WebElement elementToFindOn) {
437         try {
438             WebElement found = elementToFindOn.findElement(by);
439             WebDriverUtils.highlightElement(getDriver(), found);
440             return found;
441         } catch (Throwable t) {
442             jiraAwareFail(by.toString(), t.getMessage() + " " + this.getClass().toString(), t);
443         }
444         return null; // required by compiler, never reached
445     }
446 
447     protected boolean isLabeledTextPresent(String label, String text) {
448         WebElement element = findElement(By.xpath("//tr/th/label[contains(text(), '" + label + "')]/ancestor::tr/td"));
449         String labeledText = element.getText().trim();
450         WebDriverUtils.jGrowl(getDriver(), "Is Labeled Text Present", false, "Is text '" + text + "' present for label '" + label + "'? " + labeledText.contains(text));
451         return labeledText.contains(text);
452     }
453 
454     protected boolean isVisible(String locator) {
455         return isVisible(By.cssSelector(locator));
456     }
457 
458     protected boolean isVisible(By by) {
459         List<WebElement> elements = getDriver().findElements(by);
460         for (WebElement element: elements) {
461             if (element.isDisplayed()) {
462                 return true;
463             }
464         }
465         return false;
466     }
467 
468     protected boolean isVisibleById(String id) {
469         return isVisible(By.id(id));
470     }
471 
472     protected boolean isVisibleByXpath(String locator) {
473         return isVisible(By.xpath(locator));
474     }
475 
476     /**
477      * {@inheritDoc}
478      * {@see #checkForIncidentReport} and {@see JiraAwareFailureUtils#fail}.
479      *
480      * @param message to check for a Jira match and fail with.
481      */
482     @Override
483     public void jiraAwareFail(String message) {
484         jiraAwareFail("", message, null, this);
485     }
486 
487     /**
488      * {@inheritDoc}
489      * {@see #checkForIncidentReport} and {@see JiraAwareFailureUtils#fail}.
490      *
491      * @param contents to check for a Jira match
492      * @param message to check for a Jira match and fail with.
493      */
494     @Override
495     public void jiraAwareFail(String contents, String message) {
496         jiraAwareFail(contents, message, null, this);
497     }
498 
499     /**
500      * {@see #checkForIncidentReport} and {@see JiraAwareFailureUtils#fail}.
501      *
502      * @param by to check for a Jira match
503      * @param message to check for a Jira match and fail with.
504      * @param throwable to check for a Jira match
505      */
506     protected void jiraAwareFail(By by, String message, Throwable throwable) {
507         jiraAwareFail(by.toString(), message, throwable, this);
508     }
509 
510     /**
511      * {@inheritDoc}
512      * {@see #checkForIncidentReport} and {@see JiraAwareFailureUtils#fail}.
513      *
514      * @param contents to check for a Jira match
515      * @param message to check for a Jira match and fail with.
516      * @param throwable to check for a Jira match
517      */
518     @Override
519     public void jiraAwareFail(String contents, String message, Throwable throwable) {
520         jiraAwareFail(contents, message, throwable, this);
521     }
522 
523     /**
524      * {@see #checkForIncidentReport} and {@see JiraAwareFailureUtils#fail}.
525      *
526      * @param contents to check for a Jira match
527      * @param message to check for a Jira match and fail with.
528      * @param throwable to check for a Jira match
529      * @param failable to call fail on
530      */
531     protected void jiraAwareFail(String contents, String message, Throwable throwable, JiraAwareFailable failable) {
532         if (!contents.startsWith("\nIncident report") && !message.startsWith("\nIncident report")) {
533             String errorMessage = AutomatedFunctionalTestUtils.incidentReportMessage(getDriver().getPageSource(), "", message);
534             if (errorMessage != null) {
535                 JiraAwareFailureUtils.failOnMatchedJira(errorMessage, message, failable);
536                 JiraAwareFailureUtils.fail(errorMessage, message, throwable, failable);
537             }
538         }
539         JiraAwareFailureUtils.fail(contents, message, throwable, failable);
540     }
541 
542     /**
543      * {@see #checkForIncidentReport} and {@see JiraAwareFailureUtils#fail}.
544      *
545      * @param by to click on
546      * @param message on failure
547      * @throws InterruptedException
548      */
549     protected void jiraAwareWaitAndClick(By by, String message) throws InterruptedException {
550         jiraAwareWaitAndClick(by, message, this);
551     }
552 
553     protected WebElement jiraAwareType(By by, String text) {
554         return jiraAwareType(by, text, this.getClass().toString().replace("class ", ""));
555     }
556 
557     protected WebElement jiraAwareType(By by, String text, String failureMessage) {
558         try {
559             return type(by, text);
560         } catch (Throwable t) {
561             JiraAwareFailureUtils.failOnMatchedJira(by.toString(), failureMessage, this);
562             jiraAwareFail(t.getMessage()
563                     + " "
564                     + by.toString()
565                     + "  unable to type text '"
566                     + text
567                     + "'  "
568                     + failureMessage
569                     + " current url "
570                     + getDriver().getCurrentUrl()
571                     + "\n"
572                     + AutomatedFunctionalTestUtils.deLinespace(getDriver().getPageSource()));
573         }
574         return null;
575     }
576 
577     protected WebElement jiraAwareTypeByName(String name, String text) {
578         return jiraAwareType(By.name(name), text, this.getClass().toString().replace("class ", ""));
579     }
580 
581     protected WebElement jiraAwareTypeByName(String name, String text, String failureMessage) {
582         return jiraAwareType(By.name(name), text, failureMessage);
583     }
584 
585     /**
586      * {@see #jiraAwareWaitFor}
587      *
588      * @param by to click on
589      * @param message on failure
590      * @param failable to fail on if not found
591      * @throws InterruptedException
592      */
593     protected void jiraAwareWaitAndClick(By by, String message, JiraAwareFailable failable) throws InterruptedException {
594         try {
595             jiraAwareWaitFor(by, message, failable);
596             WebElement element = findElement(by);
597             // possible future code of outputting clicked components in a more generic way, but need to look into duplicates, don't delete
598 //            String jgrowl = element.getAttribute("name");
599 //            if (jgrowl == null || "".equals(jgrowl)) {
600 //                jgrowl = element.getAttribute("id");
601 //            }
602 //            if (jgrowl == null || "".equals(jgrowl)) {
603 //                jgrowl = by.toString();
604 //            }
605 //            WebDriverUtils.jGrowl(getDriver(), "Click " + jgrowl, false, "Click " + jgrowl);
606             element.click();
607         } catch (Throwable t) {
608             failable.jiraAwareFail(by.toString(), message, t);
609         }
610     }
611 
612     /**
613      * {@see WebDriverUtils#waitFor}.
614      *
615      * @param by to find
616      * @return WebElement found with given by
617      * @throws InterruptedException
618      */
619     protected WebElement jiraAwareWaitFor(By by) throws InterruptedException {
620         return jiraAwareWaitFor(by, this.getClass().toString());
621     }
622 
623     /**
624      * {@see WebDriverUtils#waitFor}.
625      *
626      * @param by to find
627      * @param message on failure
628      * @return WebElement found with given by
629      * @throws InterruptedException
630      */
631     protected WebElement jiraAwareWaitFor(By by, String message) throws InterruptedException {
632         try {
633             return WebDriverUtils.waitFor(getDriver(), WebDriverUtils.configuredImplicityWait(), by, message);
634         } catch (Throwable t) {
635             jiraAwareFail(by, message + " " + this.getClass().toString(), t);
636         }
637         return null; // required, but the jiraAwareFail will will end test before this statement is reached
638     }
639 
640     /**
641      * {@see WebDriverUtils#waitFor}.
642      *
643      * @param by to find
644      * @param message on failure
645      * @throws InterruptedException
646      */
647     protected void jiraAwareWaitFors(By by, String message) throws InterruptedException {
648         try {
649             WebDriverUtils.waitFors(getDriver(), WebDriverUtils.configuredImplicityWait(), by, message);
650         } catch (Throwable t) {
651             jiraAwareFail(by, message, t);
652         }
653     }
654 
655     /**
656      * {@see WebDriverUtils#waitFor}.
657      *
658      * @param by to find
659      * @param message on failure
660      * @param failable to fail if given by is not found
661      * @throws InterruptedException
662      */
663     protected void jiraAwareWaitFor(By by, String message, JiraAwareFailable failable) throws InterruptedException {
664         try {
665             WebDriverUtils.waitFor(getDriver(), WebDriverUtils.configuredImplicityWait(), by, message);
666         } catch (Throwable t) {
667             jiraAwareFail(by.toString(), message, t, failable);
668         }
669     }
670 
671     /**
672      * {@see WebDriverUtils#waitFor}.
673      *
674      * @param by to find
675      * @param seconds to wait
676      * @param message on failure
677      * @return WebElement found with given by
678      * @throws InterruptedException
679      */
680     protected WebElement jiraAwareWaitFor(By by, int seconds, String message) throws InterruptedException {
681         try {
682             return WebDriverUtils.waitFor(getDriver(), seconds, by, message);
683         } catch (Throwable t) {
684             jiraAwareFail(by, message, t);
685         }
686         return null; // required, but the jiraAwareFail will will end test before this statement is reached
687     }
688 
689     /**
690      * @return passed
691      */
692     public boolean isPassed() {
693         return passed;
694     }
695 
696     protected void selectOptionByName(String name, String optionValue) throws InterruptedException {
697         selectOption(By.name(name), optionValue);
698     }
699 
700     protected void selectOptionByXpath(String locator, String optionValue) throws InterruptedException {
701         selectOption(By.name(locator), optionValue);
702     }
703 
704     /**
705      * Uses Selenium's findElements method which does not throw a test exception if not found.
706      * @param by
707      * @param optionValue
708      * @throws InterruptedException
709      */
710     protected void selectOption(By by, String optionValue) throws InterruptedException {
711         WebElement select1 = findElement(by);
712         List<WebElement> options = select1.findElements(By.tagName("option"));
713 
714         String name = select1.getAttribute("name");
715 
716         if (options == null || options.size() == 0) {
717             jiraAwareFail("No options for select "
718                     + select1.toString()
719                     + " was looking for value "
720                     + optionValue
721                     + " using "
722                     + by.toString());
723         }
724 
725         for (WebElement option : options) {
726             if (option.getAttribute("value").equals(optionValue)) {
727                 WebDriverUtils.jGrowl(getDriver(), "Select " + option.getText(), false, "Select " + option.getText() + " from " + name);
728                 option.click();
729                 break;
730             }
731         }
732     }
733 
734     private WebElement type(By by, String text) {
735         WebElement element = findElement(by);
736         String name = element.getAttribute("name");
737         WebDriverUtils.jGrowl(getDriver(), "Type", false, "Type into " + name + " the text: " + text);
738         WebDriverUtils.highlightElement(getDriver(), element);
739         element.sendKeys(text);
740         return element;
741     }
742 
743     private WebElement typeByName(String name, String text) {
744         return type(By.name(name), text);
745     }
746 
747     /**
748      * <p>
749      * Set the test state to passed, call jGrowl sticky with success, required to be called at the conclusion of a test
750      * for the saucelabs state of a test to be updated to passed.
751      * </p>
752      */
753     protected void passed() {
754         if (passed == true) {
755             WebDriverUtils.jGrowl(getDriver(), "Passed has been called more than once " + getClass().getSimpleName(), true, "Passed");
756         }
757         passed = true;
758         WebDriverUtils.jGrowl(getDriver(), "Success " + getClass().getSimpleName(), true, "Passed");
759     }
760 
761     protected WebElement waitAndType(By by, String text, String message) throws InterruptedException {
762         try {
763             jiraAwareWaitFor(by, message);
764             return type(by, text);
765         } catch (Throwable t) {
766             JiraAwareFailureUtils.failOnMatchedJira(by.toString(), message, this);
767             jiraAwareFail(t.getMessage()
768                     + " "
769                     + by.toString()
770                     + "  unable to type text '"
771                     + text
772                     + "'  "
773                     + message
774                     + " current url "
775                     + getDriver().getCurrentUrl()
776                     + "\n"
777                     + AutomatedFunctionalTestUtils.deLinespace(getDriver().getPageSource()));
778         }
779         return null;
780     }
781 }