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.apache.commons.io.FileUtils;
19  import org.apache.commons.lang.RandomStringUtils;
20  import org.junit.After;
21  import org.junit.Before;
22  import org.junit.BeforeClass;
23  import org.junit.Rule;
24  import org.junit.rules.TestName;
25  import org.kuali.rice.testtools.common.JiraAwareFailable;
26  import org.kuali.rice.testtools.common.JiraAwareFailureUtils;
27  import org.kuali.rice.testtools.common.PropertiesUtils;
28  import org.openqa.selenium.By;
29  import org.openqa.selenium.JavascriptExecutor;
30  import org.openqa.selenium.NoSuchElementException;
31  import org.openqa.selenium.NoSuchWindowException;
32  import org.openqa.selenium.OutputType;
33  import org.openqa.selenium.TakesScreenshot;
34  import org.openqa.selenium.WebDriver;
35  import org.openqa.selenium.WebElement;
36  import org.openqa.selenium.chrome.ChromeDriverService;
37  import org.openqa.selenium.interactions.Actions;
38  import org.openqa.selenium.remote.RemoteWebDriver;
39  
40  import java.io.File;
41  import java.io.IOException;
42  import java.lang.reflect.Method;
43  import java.text.SimpleDateFormat;
44  import java.util.ArrayList;
45  import java.util.Calendar;
46  import java.util.Date;
47  import java.util.HashMap;
48  import java.util.LinkedList;
49  import java.util.List;
50  import java.util.Map;
51  import java.util.Set;
52  import java.util.concurrent.TimeUnit;
53  
54  /**
55   * <p>
56   * Originally used to upgrade UpgradedSeleniumITBase (Selenium 1.0) tests to WebDriver (Selenium 2.0).  Now there is
57   * refactoring to be done:
58   * <ol>
59   *   <li><a href="https://jira.kuali.org/browse/KULRICE-9206">KULRICE-9206</a> Replace literal strings used more than 3 times with Constants,
60   *   Javadoc constant with constant value.
61   *   <li>Extract duplicate waitAndClick...(CONSTANT) to waitAndClickConstant, Javadoc a <pre>{@link &#35;CONSTANT}</pre>.
62   *   <li>Replace large chunks of duplication</li>
63   *   <li><a href="https://jira.kuali.org/browse/KULRICE-9205">KULRICE-9205</a> Invert dependencies on fields and extract methods to WebDriverUtils
64   *   so inheritance doesn't have to be used for reuse.  See WebDriverUtils.waitFor </li>
65   *   <li>Extract Nav specific code?</li>
66   *   <li>Rename to SampleAppAftBase</li>
67   * </ol>
68   * </p>
69   * <p>Calls to passed() probably don't belong in the methods reused here.</p>
70   * @author Kuali Rice Team (rice.collab@kuali.org)
71   */
72  public abstract class WebDriverLegacyITBase extends JiraAwareAftBase {
73  
74      /**
75       * Administration
76       */
77      public static final String ADMINISTRATION_LINK_TEXT = "Administration";
78  
79      /**
80       * Agenda Lookup
81       */
82      public static final String AGENDA_LOOKUP_LINK_TEXT = "Agenda Lookup";
83  
84      /**
85       * backdoorId
86       */
87      public static final String BACKDOOR_ID_TEXT = "backdoorId";
88  
89      /**
90       * "//input[@title='Click to login.']"
91       */
92      public static final String BACKDOOR_LOGIN_BUTTON_XPATH = "//input[@title='Click to login.']";
93  
94      /**
95       * methodToCall.blanketApprove
96       */
97      public static final String BLANKET_APPROVE_NAME = "methodToCall.blanketApprove";
98  
99      /**
100      * methodToCall.cancel
101      * different cancel than CANCEL2_XPATH
102      */
103     public static final String CANCEL_NAME = "methodToCall.cancel";
104 
105     /**
106      * //a[contains(text(), 'ancel')]
107      * Different cancel than CANCEL_NAME
108      */
109     public static final String CANCEL2_XPATH = "//a[contains(text(), 'ancel')]";
110 
111     /**
112      * "//a[@title='cancel']"
113      */
114     public static final String CANCEL3_XPATH = "//a[@title='cancel']";
115 
116     /**
117      * //*[@title='close this window']
118      */
119     public static final String CLOSE_WINDOW_XPATH_TITLE = "//*[@title='close this window']";
120 
121     /**
122      * Collections
123      */
124     public static final String COLLECTIONS_LINK_TEXT = "Collections";
125 
126     /**
127      * "Kuali :: Configuration Test View"
128      */
129     public static final String CONFIGURATION_VIEW_WINDOW_TITLE = "Kuali :: Configuration Test View";
130 
131     /**
132      * (//a[contains(text(),'Configuration Test View')])[3]
133      */
134     public static final String CONFIGURATION_VIEW_XPATH = "(//a[contains(text(),'Configuration Test View')])";
135 
136     /**
137      * copy
138      */
139     public static final String COPY_LINK_TEXT = "copy";
140 
141     /**
142      * New Document not submitted successfully
143      */
144     public static final String CREATE_NEW_DOCUMENT_NOT_SUBMITTED_SUCCESSFULLY_MESSAGE_TEXT = "New Document not submitted successfully";
145 
146     /**
147      * //img[@alt='create new']
148      */
149     public static final String CREATE_NEW_XPATH = "//img[@alt='create new']";
150 
151     /**
152      * //a[@title='Create a new record']
153      */
154     public static final String CREATE_NEW_XPATH2 = "//a[@title='Create a new record']";
155 
156     /**
157      * div.dataTables_wrapper thead th
158      */
159     public static final String DATA_TABLE_TH_CSS = "div.dataTables_wrapper thead th";
160 
161     /**
162      * div.dataTables_wrapper thead th
163      */
164     public static final String DATA_TABLE_TR_CSS = "div.dataTables_wrapper tbody tr";
165 
166     /**
167      * //div[@class='left-errmsg-tab']/div/div
168      */
169     public static final String DIV_LEFT_ERRMSG = "//div[@class='left-errmsg-tab']/div/div";
170 
171     /**
172      * //input[@id='document.newMaintainableObject.code']
173      */
174     public static final String DOC_CODE_XPATH = "//input[@id='document.newMaintainableObject.code']";
175 
176     /**
177      * //div[@id='headerarea']/div/table/tbody/tr[1]/td[1]
178      */
179     public static final String DOC_ID_XPATH = "//div[@id='headerarea']/div/table/tbody/tr[1]/td[1]";
180 
181     /**
182      * //table[@id='row']/tbody/tr[1]/td[1
183      */
184     public static final String DOC_ID_XPATH_2 = "//table[@id='row']/tbody/tr[1]/td[1]";
185 
186     /**
187      * //table[@id='row']/tbody/tr[1]/td[1]/a
188      */
189     public static final String DOC_ID_XPATH_3 ="//table[@id='row']/tbody/tr[1]/td[1]/a";
190 
191     /**
192      * //input[@id='document.documentHeader.documentDescription']
193      */
194     public static final String DOC_DESCRIPTION_XPATH ="//input[@id='document.documentHeader.documentDescription']";
195 
196     /**
197      * //div[@id='headerarea']/div/table/tbody/tr[1]/td[1]
198      */
199     public static final String DOC_INITIATOR_XPATH = "//div[@id='headerarea']/div/table/tbody/tr[2]/td[1]";
200 
201     /**
202      * "//img[@alt='doc search']
203      */
204     public static final String DOC_SEARCH_XPATH = "//img[@alt='doc search']";
205 
206     /**
207      * //a[@title='Document Search']
208      */
209     public static final String DOC_SEARCH_XPATH_TITLE = "//a[@title='Document Search']";
210 
211     /**
212      * ENROUTE
213      */
214     public static final String DOC_STATUS_ENROUTE = "ENROUTE";
215 
216     /**
217      * FINAL
218      */
219     public static final String DOC_STATUS_FINAL = "FINAL";
220 
221     /**
222      * SAVED
223      */
224     public static final String DOC_STATUS_SAVED = "SAVED";
225 
226     /**
227      * //table[@class='headerinfo']//tr[1]/td[2]
228      */
229     public static final String DOC_STATUS_XPATH = "//table[@class='headerinfo']//tr[1]/td[2]";
230 
231     /**
232      * //table[@id='row']/tbody/tr[1]/td[4]
233      */
234     public static final String DOC_STATUS_XPATH_2 = "//table[@id='row']/tbody/tr[1]/td[4]";
235 
236     /**
237      * //div[contains(div,'Document was successfully submitted.')]
238      */
239     public static final String DOC_SUBMIT_SUCCESS_MSG_XPATH ="//div[contains(div,'Document was successfully submitted.')]";
240 
241     /**
242      * edit
243      */
244     public static final String EDIT_LINK_TEXT = "edit";
245 
246     /**
247      * iframeportlet
248      */
249     public static final String IFRAMEPORTLET_NAME = "iframeportlet";
250 
251     /**
252      * (//a[contains(text(),'Uif Components (Kitchen Sink)')])[2]
253      */
254     public static final String KITCHEN_SINK_XPATH = "(//a[contains(text(),'Uif Components (Kitchen Sink)')])";
255 
256     /**
257      * KRAD
258      */
259     public static final String KRAD_XPATH = "KRAD";
260 
261     /**
262      * Kuali :: Collection Totaling
263      */
264     public static final String KUALI_COLLECTION_TOTALLING_WINDOW_XPATH = "Kuali :: Collection Totaling";
265 
266     /**
267      * //a[text()='Collection Totaling']
268      */
269     public static final String KUALI_COLLECTION_TOTALLING_XPATH = "//a[text()='Collection Totaling']";
270 
271     /**
272      * Kuali :: Uif Components
273      */
274     public static final String KUALI_UIF_COMPONENTS_WINDOW_XPATH = "Kuali :: Uif Components";
275 
276     /**
277      * "Kuali :: View Title"
278      */
279     public static final String KUALI_VIEW_WINDOW_TITLE = "Kuali :: View Title";
280 
281     /**
282      * KUALI - Kuali Systems
283      */
284     public static final String LABEL_KUALI_KUALI_SYSTEMS = "KUALI - Kuali Systems";
285 
286     /**
287      * KUALI : Default
288      */
289     public static final String LABEL_KUALI_DEFAULT = "KUALI : Default";
290 
291     /**
292      * //input[@name='imageField' and @value='Logout']
293      */
294     public static final String LOGOUT_XPATH = "//input[@name='imageField' and @value='Logout']";
295 
296     /**
297      * Main Menu
298      */
299     public static final String MAIN_MENU_LINK_TEXT = "Main Menu";
300 
301     /**
302      * ^[\s\S]*error[\s\S]*$"
303      */
304     public static final String REGEX_ERROR = "^[\\s\\S]*error[\\s\\S]*$";
305 
306     /**
307      * ^[\s\S]*valid[\s\S]*$
308      */
309     public static final String REGEX_VALID = "^.*\\bvalid\\b.*$";
310 
311     /**
312      * return selected
313      */
314     public static final String RETURN_SELECTED_BUTTON_TEXT = "return selected";
315 
316     /**
317      * return value
318      */
319     public static final String RETURN_VALUE_LINK_TEXT = "return value";
320 
321     /**
322      * Kuali :: Rich Messages
323      */
324     public static final String RICH_MESSAGES_WINDOW_TITLE = "Kuali :: Rich Messages";
325 
326     /**
327      * //div[contains(div,'Document was successfully saved.')]
328      */
329     public static final String SAVE_SUCCESSFUL_XPATH = "//div[contains(div,'Document was successfully saved.')]";
330 
331     /**
332      * //input[@name='methodToCall.save' and @alt='save']
333      */
334     public static final String SAVE_XPATH="//input[@name='methodToCall.save' and @alt='save']";
335 
336     /**
337      * KIM Screens
338      * //*[@name='methodToCall.save' and @alt='save']
339      */
340     public static final String SAVE_XPATH_2 = "//*[@name='methodToCall.save' and @alt='save']";
341 
342     /**
343      * //input[@title='search' and @name='methodToCall.search']
344      */
345     public static final String SAVE_XPATH_3 = "//input[@title='search' and @name='methodToCall.search']";
346 
347     /**
348      * Search
349      */
350     public static final String SEARCH = "Search";
351 
352     /**
353      * //input[@name='methodToCall.search' and @value='search']
354      */
355     public static final String SEARCH_XPATH="//input[@name='methodToCall.search' and @value='search']";
356 
357     /**
358      * //input[@value='search']
359      */
360     public static final String SEARCH_XPATH_2 = "//input[@value='search']";
361 
362     /**
363      * //button[contains(text(),'Search')]
364      */
365     public static final String SEARCH_XPATH_3 = "//button[contains(text(),'earch')]";
366 
367     /**
368      * (//input[@name='methodToCall.search'])[2]
369      */
370     public static final String SEARCH_SECOND = "(//input[@name='methodToCall.search'])[2]";
371 
372     /**
373      * //input[@name='methodToCall.route' and @alt='submit']
374      */
375     public static final String SUBMIT_XPATH="//input[@name='methodToCall.route' and @alt='submit']";
376 
377     /**
378      * div.uif-group.uif-collectionGroup.uif-tableCollectionGroup.uif-tableSubCollection.uif-disclosure span.uif-headerText-span
379      */
380     public static final String SUB_COLLECTION_UIF_DISCLOSURE_SPAN_UIF_HEADER_TEXT_SPAN_XPATH =
381             "div.uif-group.uif-collectionGroup.uif-tableCollectionGroup.uif-tableSubCollection.uif-disclosure span.uif-headerText-span";
382 
383     /**
384      * timeout
385      */
386     public static final String TIMEOUT_MESSAGE = "timeout";
387 
388     /**
389      * Travel Account Lookup
390      */
391     public static final String TRAVEL_ACCOUNT_LOOKUP_LINK_TEXT = "Travel Account Lookup";
392 
393     /**
394      * Uif Components (Kitchen Sink)
395      */
396     public static final String UIF_COMPONENTS_KITCHEN_SINK_LINK_TEXT = "Uif Components (Kitchen Sink)";
397 
398     /**
399      * (//a[contains(text(),'Validation Framework Demo')])[2]
400      */
401     public static final String VALIDATION_FRAMEWORK_DEMO_XPATH = "(//a[contains(text(),'Validation Framework Demo')])";
402 
403     /**
404      * XML Ingester
405      */
406     public static final String XML_INGESTER_LINK_TEXT = "XML Ingester";
407 
408     /**
409      * //a[@title='FiscalOfficerInfo Maintenance (New)']
410      */
411     public static final String FISCAL_OFFICER_INFO_MAINTENANCE_NEW_XPATH = "//a[@title='FiscalOfficerInfo Maintenance (New)']";
412 
413     static ChromeDriverService chromeDriverService;
414 
415     static {
416         if (System.getProperty(WebDriverUtils.REMOTE_PROPERTIES_PROPERTY) != null) {
417             PropertiesUtils propUtils = new PropertiesUtils();
418             try {
419                 propUtils.loadPropertiesWithSystemAndOverridesIntoSystem(System.getProperty(WebDriverUtils.REMOTE_PROPERTIES_PROPERTY));
420             } catch (IOException ioe) {
421                 System.out.println("Exception opening " + System.getProperty(WebDriverUtils.REMOTE_PROPERTIES_PROPERTY) + " " + ioe.getMessage());
422             }
423         }
424     }
425 
426     protected WebDriver driver;
427 
428     protected String namespaceCode = "KR-WKFLW";
429 
430     protected String user = "admin";
431     protected int waitSeconds;
432     protected String uiFramework = AutomatedFunctionalTestUtils.REMOTE_UIF_KNS;   // default to KNS
433 
434     protected String uniqueString;
435 
436     public @Rule
437     TestName testName = new TestName();
438 
439     protected String testMethodName;
440 
441     protected String jGrowlHeader;
442 
443     String sessionId = null;
444 
445     private static final Map<String, String> actionRequestLabelMap;
446     private static Map<String, String> actionRequestButtonMap;
447     static{
448         actionRequestLabelMap = new HashMap();
449         actionRequestLabelMap.put("A","APPROVE");
450         actionRequestLabelMap.put("F","FYI");
451         actionRequestLabelMap.put("C","COMPLETE");
452         actionRequestLabelMap.put("K","ACKNOWLEDGE");
453         actionRequestLabelMap.put("D","APPROVE");
454         actionRequestButtonMap = new HashMap();
455         actionRequestButtonMap.put("A","methodToCall.approve");
456         actionRequestButtonMap.put("F","methodToCall.fyi");
457         actionRequestButtonMap.put("C","methodToCall.complete");
458         actionRequestButtonMap.put("K","methodToCall.acknowledge");
459         actionRequestButtonMap.put("D","methodToCall.disapprove");
460     }
461     
462     /**
463      * If WebDriverUtils.chromeDriverCreateCheck() returns a ChromeDriverService, start it.
464      * {@link WebDriverUtils#chromeDriverCreateCheck()}
465      * @throws Exception
466      */
467     @BeforeClass
468     public static void chromeDriverService() throws Exception {
469         chromeDriverService = WebDriverUtils.chromeDriverCreateCheck();
470         if (chromeDriverService != null)
471             chromeDriverService.start();
472     }
473 
474     /**
475      * <p>
476      * Logs in using the KRAD Login Page, if the JVM arg remote.autologin is set, auto login as admin will not be done.
477      * </p>
478      *
479      * @param driver to login with
480      * @param userName to login with
481      * @param failable to fail on if there is a login problem
482      * @throws InterruptedException
483      */
484     public static void loginKrad(WebDriver driver, String userName, JiraAwareFailable failable) throws InterruptedException {
485         driver.findElement(By.name("login_user")).clear();
486         driver.findElement(By.name("login_user")).sendKeys(userName);
487         driver.findElement(By.id("Rice-LoginButton")).click();
488         Thread.sleep(1000);
489         String contents = driver.getPageSource();
490         AutomatedFunctionalTestUtils.failOnInvalidUserName(userName, contents, failable);
491         AutomatedFunctionalTestUtils.checkForIncidentReport(driver.getPageSource(), "Krad Login",
492                 "Krad Login failure", failable);
493     }
494 
495     /**
496      * <p>
497      * Logs into the Rice portal using the KNS Style Login Page.
498      * </p>
499      *
500      * @param driver to login with
501      * @param userName to login with
502      * @param failable to fail on if there is a login problem
503      * @throws InterruptedException
504      */
505     public static void login(WebDriver driver, String userName, JiraAwareFailable failable) throws InterruptedException {
506         driver.findElement(By.name("__login_user")).clear();
507         driver.findElement(By.name("__login_user")).sendKeys(userName);
508         driver.findElement(By.cssSelector("input[type=\"submit\"]")).click();
509         Thread.sleep(1000);
510         String contents = driver.getPageSource();
511         AutomatedFunctionalTestUtils.failOnInvalidUserName(userName, contents, failable);
512         AutomatedFunctionalTestUtils.checkForIncidentReport(driver.getPageSource(), "KNS Login",
513                 "KNS Login failure", failable);
514     }
515 
516     /**
517      * <p>
518      * Login as KRAD or KNS if {@see #REMOTE_AUTOLOGIN_PROPERTY} is not set to true.
519      * </p>
520      *
521      * @param driver to login with
522      * @param user to login with
523      * @param failable to fail on if there is a login problem
524      * @throws InterruptedException
525      */
526     public static void loginKradOrKns(WebDriver driver, String user, JiraAwareFailable failable) throws InterruptedException {// login via either KRAD or KNS login page
527         if ("true".equalsIgnoreCase(System.getProperty(WebDriverUtils.REMOTE_AUTOLOGIN_PROPERTY, "true"))) {
528             if (AutomatedFunctionalTestUtils.isKradLogin()){
529                 loginKrad(driver, user, failable);
530             } else {
531                 login(driver, user, failable);
532             }
533         }
534     }
535 
536     protected void startSession(Method method) throws Exception {
537         testMethodName = method.getName(); // TestNG
538     }
539 
540     /**
541      * 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.
542      * Setup the WebDriver properties, test, and login.  Named testSetUp so it runs after TestNG's startSession(Method)
543      * {@link WebDriverUtils#determineUser(String)}
544      * {@link WebDriverUtils#setUp(String, String, String, String)}
545      */
546     @Before
547     public void testSetUp() {
548         // 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.
549         try { // Don't throw any exception from this methods, exceptions in Before annotations really mess up maven, surefire, or failsafe
550             if (testName != null && testName.getMethodName() != null) { // JUnit
551                 testMethodName = testName.getMethodName();
552             }
553 
554             waitSeconds = WebDriverUtils.configuredImplicityWait();
555             String givenUser = WebDriverUtils.determineUser(this.toString());
556             if (givenUser != null) {
557                 user = givenUser;
558             }
559 
560             String testUrl = kulrice9804(); // https://jira.kuali.org/browse/KULRICE-9804 KNS Create new link absent when Bookmark URL requires Login
561 
562             driver = WebDriverUtils.setUp(getUserName(), testUrl, getClass().getSimpleName(), testMethodName);
563             this.sessionId = ((RemoteWebDriver) driver).getSessionId().toString();
564 
565             jGrowlHeader = getClass().getSimpleName() + "." + testMethodName;
566             System.out.println(jGrowlHeader + " sessionId is " + sessionId);
567             WebDriverUtils.jGrowl(driver, "Open URL", false, "Open " + testUrl);
568             loginKradOrKns(driver, user, this);
569 
570             navigateInternal(); // SeleniumBaseTest.fail from navigateInternal results in the test not being recorded as a failure in CI.
571 
572         } catch (Throwable t) {
573             System.out.println("Throwable " + t.getMessage() + " in Before annotated method is very bad, ignoring and letting first method of test class to fail.");
574             t.printStackTrace();
575             System.out.println("Throwable " + t.getMessage() + " in Before annotated method is very bad, ignoring and letting first method of test class to fail.");
576         }
577     }
578 
579     /**
580      * // https://jira.kuali.org/browse/KULRICE-9804 KNS Create new link absent when Bookmark URL requires Login
581      * @return
582      */
583     private String kulrice9804() {
584         String testUrl = getTestUrl();
585         if (testUrl.contains(AutomatedFunctionalTestUtils.HIDE_RETURN_LINK) &&
586                 !testUrl.contains("&showMaintenanceLinks=true")) {
587             testUrl += "&showMaintenanceLinks=true";
588         }
589         return testUrl;
590     }
591 
592     /**
593      * Tear down test as configured.  Do not allow exceptions to be thrown by tearDown, it kills the test run.
594      * {@link WebDriverUtils#tearDown(boolean, String, String, String)}
595      * {@link WebDriverUtils#REMOTE_PUBLIC_USERPOOL_PROPERTY}
596      * {@link WebDriverUtils#dontTearDownPropertyNotSet()}
597      * @throws Exception
598      */
599     @After
600     public void tearDown() {
601         try {
602             if (isPassed() && WebDriverUtils.dontTearDownPropertyNotSet() && WebDriverUtils.dontTearDownOnFailure(isPassed())) {
603                 waitAndClickLogoutIfPresent();
604             } else {
605                 System.out.println("Last AFT URL: " + driver.getCurrentUrl());
606                 if ("true".equals(System.getProperty("remote.driver.failure.screenshot", "true")) || screenshotSteps()) {
607                     screenshot();
608                 }
609             }
610             WebDriverUtils.tearDown(isPassed(), sessionId, this.toString().trim(), user);
611         } catch (Throwable t) {
612             System.out.println("Exception in tearDown " + t.getMessage());
613             t.printStackTrace();
614         }
615 
616         finally {
617             try {
618                 closeAndQuitWebDriver();
619             } catch (Throwable t) {
620                 System.out.println(t.getMessage() + " occurred during tearDown, ignoring to avoid killing test run.");
621                 t.printStackTrace();
622                 System.out.println(t.getMessage() + " occurred during tearDown, ignoring to avoid killing test run.");
623             }
624         }
625     }
626 
627     private void closeAndQuitWebDriver() {
628         if (driver != null) {
629             if (WebDriverUtils.dontTearDownPropertyNotSet() && WebDriverUtils.dontTearDownOnFailure(isPassed())) {
630                 try {
631                     driver.close();
632                 } catch (NoSuchWindowException nswe) {
633                     System.out.println("NoSuchWindowException closing WebDriver " + nswe.getMessage());
634                 } finally {
635                     if (driver != null) {
636                         driver.quit();
637                     }
638                 }
639             }
640         } else {
641             System.out.println("WebDriver is null for " + this.getClass().toString() + " if using a remote hub did you include the port?");
642         }
643     }
644 
645     @Override
646     protected String getNavigationUrl() {
647         String classString = this.getClass().toString();
648         if (classString.contains("krad.demo")) {
649             return AutomatedFunctionalTestUtils.KRAD_PORTAL;
650         } else if (classString.contains("krad.labs")) {
651             return AutomatedFunctionalTestUtils.LABS;
652         } else {
653             return AutomatedFunctionalTestUtils.PORTAL;
654         }
655     }
656 
657 
658     @Override
659     protected void navigate() throws Exception {
660         // No-op for convenience
661     }
662 
663     protected void impersonateUser(String user) throws InterruptedException {
664         waitAndTypeByName(BACKDOOR_ID_TEXT,user);
665         jGrowl("Click Backdoor Login");
666         waitAndClickByXpath(BACKDOOR_LOGIN_BUTTON_XPATH);
667     }
668 
669     protected void addAdHocRecipientsGroup(String[] adHocRecipients) throws InterruptedException {
670         addAdHocRecipientsGroup(new String[][]{adHocRecipients});
671     }
672 
673     protected void addAdHocRecipientsGroup(String[][] adHocRecipients) throws InterruptedException {
674         String today = getDateToday();
675         Calendar nextYearCal = Calendar.getInstance();
676         nextYearCal.add(Calendar.YEAR, 1);
677         SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
678         String nextYear = sdf.format(nextYearCal.getTime());
679 
680         waitAndClickByName("methodToCall.toggleTab.tabAdHocRecipients");
681         for (int i = 0, s = adHocRecipients.length; i < s; i++) {
682             selectOptionByName("newAdHocRouteWorkgroup.actionRequested", adHocRecipients[i][1]);
683             waitAndTypeByName("newAdHocRouteWorkgroup.recipientName", adHocRecipients[i][0]);
684             waitAndTypeByName("newAdHocRouteWorkgroup.recipientNamespaceCode", adHocRecipients[i][2]);
685             WebDriverUtils.jGrowl(getDriver(), "Click Add Group", false, "Click Add Group");
686             waitAndClickByName("methodToCall.insertAdHocRouteWorkgroup");
687         }
688     }
689 
690     /**
691      * @param adHocRecipients user, action option value
692      * @throws InterruptedException
693      */
694     protected void addAdHocRecipientsPerson(String[] adHocRecipients) throws InterruptedException {
695         addAdHocRecipientsPerson(new String[][]{adHocRecipients});
696     }
697 
698     /**
699      * @param adHocRecipients user, action option value
700      * @throws InterruptedException
701      */
702     protected void addAdHocRecipientsPerson(String[][] adHocRecipients) throws InterruptedException {
703         String today = getDateToday();
704         Calendar nextYearCal = Calendar.getInstance();
705         nextYearCal.add(Calendar.YEAR, 1);
706         SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
707         String nextYear = sdf.format(nextYearCal.getTime());
708 
709         waitAndClickByName("methodToCall.toggleTab.tabAdHocRecipients");
710         for (int i = 0, s = adHocRecipients.length; i < s; i++) {
711             selectOptionByName("newAdHocRoutePerson.actionRequested", adHocRecipients[i][1]);
712             waitAndTypeByName("newAdHocRoutePerson.id", adHocRecipients[i][0]);
713 //            if (isElementPresentByName("member.activeFromDate")) {
714 //                waitAndTypeByName("member.activeFromDate", today);
715 //            }
716 //            if (isElementPresentByName("member.activeFromDate")) {
717 //                waitAndTypeByName("member.activeFromDate", nextYear);
718 //            }
719             WebDriverUtils.jGrowl(getDriver(), "Click Add Person", false, "Click Add Person");
720             waitAndClickByName("methodToCall.insertAdHocRoutePerson");
721         }
722     }
723 
724     protected void agendaLookupAssertions() throws Exception {
725         testLookUp();
726         assertTextPresent("Rules");
727         waitAndClick(By.xpath(CANCEL2_XPATH));
728     }
729 
730     /**
731      * Accept the javascript alert (clicking OK)
732      */
733     protected void alertAccept() {
734         WebDriverUtils.alertAccept(driver);
735     }
736 
737     /**
738      * Dismiss the javascript alert (clicking Cancel)
739      */
740     protected void alertDismiss() {
741         WebDriverUtils.alertDismiss(driver);
742     }
743 
744     protected boolean areAllMultiValueSelectsChecked() throws InterruptedException {
745         acceptAlertIfPresent();
746         WebElement tbody = waitAndGetElementByAttributeValue("role", "alert"); // results table body
747         List<WebElement> checkboxes = findElements(By.className("uif-checkboxControl"),tbody);
748         for (WebElement checkbox: checkboxes) {
749             if (!"true".equals(checkbox.getAttribute("checked"))) {
750                 return false;
751             }
752         }
753         return true;
754     }
755 
756     protected boolean areNoMultiValueSelectsChecked() throws InterruptedException {
757         WebElement tbody = waitAndGetElementByAttributeValue("role", "alert"); // results table body
758         List<WebElement> checkboxes = findElements(By.className("uif-checkboxControl"),tbody);
759         for (WebElement checkbox: checkboxes) {
760             if (null != checkbox.getAttribute("checked")) {
761                 return false;
762             }
763         }
764         return true;
765     }
766 
767     protected void assertActionList(String docId, String actionListOptionValue, String state) throws InterruptedException {
768         selectTopFrame();
769         waitAndClickActionList();
770         selectFrameIframePortlet();
771         while (!waitForIsTextPresent(docId)) {
772             waitAndClickByLinkText("Next");
773         }
774         WebElement docIdTr = findElement(By.xpath("//table/tbody/tr/td/a[contains(text(), '" + docId + "')]/../.."));
775         assertTrue(docIdTr.getText() + " does not contain " + docId, docIdTr.getText().contains(docId));
776         assertTrue(docIdTr.getText() + " does not contain " + state, docIdTr.getText().contains(state));
777         assertTrue(docIdTr.getText() + " does not contain " + actionRequestLabelMap.get(actionListOptionValue), docIdTr.getText().contains(actionRequestLabelMap.get(actionListOptionValue)));
778 //        assertTextPresent(new String[]{docId, actionRequestLabelMap.get(actionListOptionValue)});
779         waitAndClickLinkContainingText(docId);
780         selectChildWindow();
781         waitAndClickByName(actionRequestButtonMap.get(actionListOptionValue));
782 
783         // Disapprove requires another step before checking outbox
784         if ("D".equals(actionListOptionValue)) {
785             waitAndTypeByName("reason","disapproved for AFT");
786             jGrowl("Click yes button");
787             waitAndClickByName("methodToCall.processAnswer.button0");
788         } else if ("C".equals(actionListOptionValue)) {
789             waitAndClickByName("methodToCall.close");
790         }
791         waitForTextNotPresent(docId);
792         assertOutbox(docId);
793     }
794 
795     protected void assertOutbox(String docId) throws InterruptedException {
796         // find it in outbox
797         waitAndClickLinkContainingText("Outbox");
798         while (!waitForIsTextPresent(docId)) {
799             waitAndClickByLinkText("Next");
800         }
801         waitForTextPresent(docId);
802 
803 //        // clear all items in the outbox
804 //        waitAndClickAllByName("outboxItems");
805 //        waitAndClickByName("methodToCall.removeOutboxItems");
806     }
807 
808     protected void assertAttributeClassRegexDoesntMatch(String field, String regex) throws InterruptedException {
809         Thread.sleep(1000);
810         String attribute = waitAndGetAttributeByName(field, "class");
811         assertTrue("waitAndGetAttributeByName(" + field + ", \"class\") should not be null", attribute != null);
812         assertFalse("attribute " + attribute + " matches regex " + regex + " and it should not", attribute.matches(
813                 regex));
814     }
815 
816     protected void assertAttributeClassRegexMatches(String field, String regex) throws InterruptedException {
817         Thread.sleep(1000);
818         String attribute = waitAndGetAttributeByName(field, "class");
819         assertTrue("waitAndGetAttributeByName(" + field + ", \"class\") should not be null", attribute != null);
820         assertTrue("attribute " + attribute + " doesn't match regex " + regex, attribute.matches(regex));
821     }
822 
823     protected void assertBlanketApproveButtonsPresent() {
824         assertElementPresentByName("methodToCall.route");
825         assertElementPresentByName("methodToCall.save");
826         assertElementPresentByName(BLANKET_APPROVE_NAME, "Blanket Approve button not present does " + user + " have permssion?");
827         assertElementPresentByName("methodToCall.close");
828         assertElementPresentByName(CANCEL_NAME);
829     }
830 
831     protected void assertCancelConfirmation() throws InterruptedException {
832         waitAndClickByLinkText("Cancel");
833         alertDismiss();
834     }
835 
836     protected void assertDocFinal(String docId) throws InterruptedException {
837         assertDocSearch(docId, DOC_STATUS_FINAL);
838     }
839 
840     protected void assertDocSearch(String docId, String docStatus) throws InterruptedException {
841         docSearch(docId);
842         waitForElementPresentByXpath(DOC_ID_XPATH_3);
843         assertEquals(docId, getTextByXpath(DOC_ID_XPATH_3));
844         assertEquals(docStatus, getTextByXpath(DOC_STATUS_XPATH_2));
845     }
846 
847     private void docSearch(String docId) throws InterruptedException {
848         selectParentWindow();
849         selectTopFrame();
850         waitAndClickDocSearchTitle();
851         waitForPageToLoad();
852         selectFrameIframePortlet();
853         waitAndTypeByName("documentId", docId);
854         waitAndClickSearch();
855     }
856 
857     protected void assertDocSearchNoResults(String docId) throws InterruptedException {
858         docSearch(docId);
859         waitForTextPresent("No values match this search.");
860     }
861 
862     protected void assertFocusTypeBlurError(String field, String textToType) throws InterruptedException {
863         fireEvent(field, "focus");
864         waitAndTypeByName(field, textToType);
865         fireEvent(field, "blur");
866         Thread.sleep(500);
867         assertAttributeClassRegexMatches(field, REGEX_ERROR);
868     }
869 
870     protected void assertFocusTypeBlurError(String field, String[] errorInputs) throws InterruptedException {
871         for (String errorInput: errorInputs) {
872             assertFocusTypeBlurError(field, errorInput);
873             clearTextByName(field);
874         }
875     }
876 
877     protected void assertFocusTypeBlurValid(String field, String textToType) throws InterruptedException {
878         fireEvent(field, "focus");
879         waitAndTypeByName(field, textToType);
880         fireEvent(field, "blur");
881         Thread.sleep(200);
882         assertAttributeClassRegexMatches(field, REGEX_VALID);
883         assertAttributeClassRegexDoesntMatch(field, REGEX_ERROR);
884     }
885 
886     protected void assertFocusTypeBlurValid(String field, String[] validInputs) throws InterruptedException {
887         for (String validInput: validInputs) {
888             assertFocusTypeBlurValid(field, validInput);
889             clearTextByName(field);
890         }
891     }
892 
893     protected void assertJgrowlText(String jGrowlText) throws InterruptedException {
894         waitForElementPresentByClassName("jGrowl-message");
895 
896         // wait for any flash not present errors to fade out
897         while (findElement(By.className("jGrowl-message")).getText().contains("Unable to load SWF file")) {
898             driver.findElement(By.className("jGrowl-close")).click(); // no wait, click quick
899         }
900 
901         // get growl texts
902         StringBuilder sb = new StringBuilder("");
903         List<WebElement> jGrowls = findElements(By.className("jGrowl-message"));
904         for (WebElement jGrowl : jGrowls) {
905             if (jGrowl.getText() != null) {
906                 sb.append(jGrowl.getText()).append("\n");
907             }
908         }
909         String growlText = sb.toString();
910 
911         WebDriverUtils.stepMessage("Do jGrowls contain text '" + jGrowlText + "'? " + growlText.contains(jGrowlText));
912 
913         //check growl text is present
914         assertTrue(growlText + " does not contain " + jGrowlText, growlText.contains(jGrowlText));
915     }
916 
917     protected void assertLabelWithTextPresent(String labelText) throws InterruptedException {
918         jGrowl("Assert Label containing the text " + labelText + " is present");
919         waitForElementPresentByXpath("//label[contains(text(), '" + labelText + "')]");
920     }
921 
922     protected void assertLabelFor(String forElementId, String labelText) {
923         assertEquals(labelText, getForLabelText(forElementId));
924     }
925 
926     protected void assertMultiValueDeselectAllThisPage() throws InterruptedException {
927         waitAndClickDropDown("deselect all items on this page");
928         if (!areNoMultiValueSelectsChecked()) {
929             jiraAwareFail("deselect all items on this page failure");
930         }
931         assertButtonDisabledByText(RETURN_SELECTED_BUTTON_TEXT);
932     }
933 
934     protected void assertMultiValueSelectAllThisPage() throws InterruptedException {
935         waitAndClickDropDown("select all items on this page");
936         if (!areAllMultiValueSelectsChecked()) {
937             JiraAwareFailureUtils.fail("select all items on this page failure", this);
938         }
939         assertButtonEnabledByText(RETURN_SELECTED_BUTTON_TEXT);
940     }
941 
942     /**
943      * Assert that clicking an element causes a popup window with a specific URL
944      * Uses Selenium's findElements method which does not throw a test exception if not found.
945      * @param by The locating mechanism of the element to be clicked
946      * @param windowName The name of the popup window
947      * @param url The URL of the popup window
948      */
949     protected void assertPopUpWindowUrl(By by, String windowName, String url) {
950         findElement(by).click();
951         String parentWindowHandle = driver.getWindowHandle();
952         // wait page to be loaded
953         driver.switchTo().window(windowName).findElements(By.tagName("head"));
954         assertEquals(url, driver.getCurrentUrl());
955         driver.switchTo().window(parentWindowHandle);
956     }
957 
958     protected void assertTableLayout() {
959         String pageSource = driver.getPageSource();
960         assertTrue(pageSource.contains("Table Layout"));
961         assertTrue(pageSource.contains("Field 1"));
962         assertTrue(pageSource.contains("Field 2"));
963         assertTrue(pageSource.contains("Field 3"));
964         assertTrue(pageSource.contains("Field 4"));
965         assertTrue(pageSource.contains("Actions"));
966     }
967 
968     protected void assertTextPresent(String[] text) throws InterruptedException {
969         StringBuilder missingText = new StringBuilder("");
970         boolean present = true;
971         for (int i = 0, s = text.length; i < s; i++) {
972             if (i == 0) {
973                 present = waitForIsTextPresent(text[0]); // wait for the first check
974                 if (!present) {
975                     missingText.append(text[0]);
976                 }
977             } else {
978                 if (!isTextPresent(text[i])) {
979                     present = false;
980                     missingText.append(" " + text[i]);
981                 }
982             }
983         }
984         if (!present) {
985             jiraAwareFail(missingText + " not present for " + this.getClass().toString());
986         }
987     }
988 
989     protected void assertTextPresent(String[][] text) throws InterruptedException {
990         StringBuilder missingText = new StringBuilder("");
991         boolean present = true;
992         for (int i = 0, s = text.length; i < s; i++) {
993             for (int j = 0, t = text[i].length; j < t; j++) {
994                 if (i == 0 && j == 0) {
995                     present = waitForIsTextPresent(text[0][0]); // wait for the first check
996                     if (!present) {
997                         missingText.append(text[0][0]);
998                     }
999                 } else {
1000                     if (!isTextPresent(text[i][j])) {
1001                         present = false;
1002                         missingText.append(" " + text[i][j]);
1003                     }
1004                 }
1005             }
1006         }
1007         if (!present) {
1008             jiraAwareFail(missingText + " not present for " + this.getClass().toString());
1009         }
1010     }
1011 
1012     protected void back() {
1013         driver.navigate().back();
1014     }
1015 
1016     private void blanketApproveAssert(String docId) throws InterruptedException {
1017         checkForDocError();
1018         assertDocSearch(docId, DOC_STATUS_FINAL);
1019     }
1020 
1021     protected void blanketApproveCheck() throws InterruptedException {
1022         waitAndClickByName(BLANKET_APPROVE_NAME,
1023                 "No blanket approve button does the user " + getUserName() + " have permission?");
1024     }
1025 
1026     /**
1027      * Tests blanket approve action.
1028      * This method is used by several different tests which perform various types of blanket approvals.
1029      * Therefore, this is a candidate to remain in this base class
1030      *
1031      * @throws InterruptedException
1032      */
1033     protected void blanketApproveTest(String docId) throws InterruptedException {
1034         jGrowl("Click Blanket Approve");
1035         waitAndClickByName(BLANKET_APPROVE_NAME,
1036                 "No blanket approve button does the user " + getUserName() + " have permission?");
1037         Thread.sleep(2000);
1038 
1039         blanketApproveAssert(docId);
1040     }
1041 
1042     protected void check(By by) throws InterruptedException {
1043         WebElement element = findElement(by);
1044 
1045         if (!element.isSelected()) {
1046             element.click();
1047         }
1048     }
1049 
1050     protected void checkById(String id) throws InterruptedException {
1051         check(By.id(id));
1052     }
1053 
1054     protected void checkByName(String name) throws InterruptedException {
1055         check(By.name(name));
1056     }
1057 
1058     protected void checkByXpath(String locator) throws InterruptedException {
1059         check(By.xpath(locator));
1060     }
1061 
1062     protected void checkErrorMessageItem(String message) {
1063         final String error_locator = "//li[@class='uif-errorMessageItem']";
1064         assertElementPresentByXpath(error_locator);
1065         String errorText = null;
1066 
1067         try {
1068             errorText = getTextByXpath(error_locator);
1069         } catch (InterruptedException e) {
1070             e.printStackTrace();
1071         }
1072 
1073         if (errorText != null && errorText.contains("errors")) {
1074             jiraAwareFail(errorText + message);
1075         }
1076     }
1077 
1078     /**
1079      * Uses Selenium's findElements method which does not throw a test exception if not found.
1080      */
1081     public void checkForDocError() {
1082         if (hasDocError()) {
1083             String errorText = extractErrorText();
1084             jiraAwareFail(errorText);
1085         }
1086     }
1087 
1088     protected String extractErrorText() {
1089         String errorText = driver.findElement(By.xpath(AutomatedFunctionalTestUtils.DIV_ERROR_LOCATOR)).getText(); // don't highlight
1090         errorText = AutomatedFunctionalTestUtils.blanketApprovalCleanUpErrorText(errorText);
1091         if (driver.findElements(By.xpath(AutomatedFunctionalTestUtils.DIV_EXCOL_LOCATOR)).size() > 0) { // not present if errors are at the bottom of the page (see left-errmsg below)
1092             errorText = AutomatedFunctionalTestUtils.blanketApprovalCleanUpErrorText(driver.findElement(
1093                     // don't highlight
1094                     By.xpath(AutomatedFunctionalTestUtils.DIV_EXCOL_LOCATOR)).getText()); // replacing errorText as DIV_EXCOL_LOCATOR includes the error count
1095         }
1096         if (driver.findElements(By.xpath(DIV_LEFT_ERRMSG)).size() > 0) {
1097             errorText = errorText + AutomatedFunctionalTestUtils.blanketApprovalCleanUpErrorText(driver.findElement(
1098                     By.xpath(DIV_LEFT_ERRMSG)).getText()); // don't highlight
1099         }
1100         return errorText;
1101     }
1102 
1103     /**
1104      * Uses Selenium's findElements method which does not throw a test exception if not found.
1105      * @return
1106      */
1107     public boolean hasDocError() {
1108         if (driver.findElements(By.xpath(AutomatedFunctionalTestUtils.DIV_ERROR_LOCATOR)).size() > 0) {
1109             String errorText = driver.findElement(By.xpath(AutomatedFunctionalTestUtils.DIV_ERROR_LOCATOR)).getText(); // don't highlight
1110             if (errorText != null && errorText.contains("error(s) found on page.")) {
1111                 return true;
1112             }
1113         }
1114         return false;
1115     }
1116 
1117     /**
1118      * Uses Selenium's findElements method which does not throw a test exception if not found.
1119      * @param errorTextToMatch
1120      * @return
1121      */
1122     public boolean hasDocError(String errorTextToMatch) {
1123         if (driver.findElements(By.xpath(AutomatedFunctionalTestUtils.DIV_ERROR_LOCATOR)).size() > 0) {
1124             String errorText = driver.findElement(By.xpath(AutomatedFunctionalTestUtils.DIV_ERROR_LOCATOR)).getText(); // don't highlight
1125             if (errorText != null && errorText.contains("error(s) found on page.")) {
1126                 WebElement errorDiv = driver.findElement(By.xpath("//div[@class='left-errmsg']/div[2]/div")); // don't highlight
1127                 if (errorDiv != null) {
1128                     errorText = errorDiv.getText();
1129                     return errorText != null && errorText.contains(errorTextToMatch);
1130                 }
1131             }
1132         }
1133         return false;
1134     }
1135 
1136     protected void checkForIncidentReport() {
1137         checkForIncidentReport("", this.getClass().toString());
1138     }
1139 
1140     protected String incidentReportMessage() {
1141         return AutomatedFunctionalTestUtils.incidentReportMessage(driver.getPageSource(), "", this.getClass().toString());
1142     }
1143 
1144     protected void checkForIncidentReport(String locator) {
1145         checkForIncidentReport(locator, this.getClass().toString());
1146     }
1147 
1148     protected void checkForIncidentReport(String locator, String message) {
1149         AutomatedFunctionalTestUtils.checkForIncidentReport(driver.getPageSource(), locator, message, this);
1150     }
1151 
1152     /**
1153      * @deprecated {@see #checkForIncidentReport(String, String)}
1154      */
1155     protected void checkForIncidentReport(String locator, JiraAwareFailable failable, String message) {
1156         AutomatedFunctionalTestUtils.checkForIncidentReport(driver.getPageSource(), locator, message, failable);
1157     }
1158 
1159     protected void clearText(By by) throws InterruptedException {
1160         findElement(by).clear();
1161     }
1162 
1163     protected void clearText(String selector) throws InterruptedException {
1164         clearText(By.cssSelector(selector));
1165     }
1166 
1167     protected void clearTextByName(String name) throws InterruptedException {
1168         clearText(By.name(name));
1169     }
1170 
1171     protected void clearTextByXpath(String locator) throws InterruptedException {
1172         clearText(By.xpath(locator));
1173     }
1174 
1175     protected void close() {
1176         driver.close();
1177     }
1178 
1179     protected void colapseExpandByXpath(String clickLocator, String visibleLocator) throws InterruptedException {
1180         waitAndClickByXpath(clickLocator);
1181         waitNotVisibleByXpath(visibleLocator);
1182         waitAndClickByXpath(clickLocator);
1183         waitIsVisibleByXpath(visibleLocator);
1184     }
1185 
1186     protected String configNameSpaceBlanketApprove() throws Exception {
1187         String docId = waitForDocId();
1188         String dtsPlusTwoChars = AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
1189         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Validation Test Namespace " + AutomatedFunctionalTestUtils
1190                 .createUniqueDtsPlusTwoRandomCharsNot9Digits());
1191         assertBlanketApproveButtonsPresent();
1192         waitAndTypeByXpath(DOC_CODE_XPATH, "VTN" + dtsPlusTwoChars);
1193         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.name']",
1194                 "Validation Test NameSpace " + dtsPlusTwoChars);
1195         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.applicationId']", "RICE");
1196 
1197         return docId;
1198     }
1199 
1200     protected void contextLookupAssertions() throws Exception {
1201         testLookUp();
1202         assertTextPresent("Notes and Attachments");
1203         waitAndClick(By.xpath(CANCEL2_XPATH));
1204         passed();
1205     }
1206 
1207     //    protected void deleteSubCollectionLine() throws Exception {
1208     //        // click on collections page link
1209     //        waitAndClickByLinkText(COLLECTIONS_LINK_TEXT);
1210     //        Thread.sleep(5000);
1211     //
1212     //        // wait for collections page to load by checking the presence of a sub collection line item
1213     //        waitForElementPresentByName("list4[0].subList[0].field1");
1214     //
1215     //        // change a value in the line to be deleted
1216     //        waitAndTypeByName("list4[0].subList[0].field1", "selenium");
1217     //
1218     //        // click the delete button
1219     //        waitAndClickByXpath("//div[@id='collection4_disclosureContent']/div[@class='uif-stackedCollectionLayout']/div[@class='uif-group uif-gridGroup uif-collectionItem uif-gridCollectionItem']/table/tbody/tr[5]/td/div/fieldset/div/div[@class='uif-disclosureContent']/div[@class='dataTables_wrapper']/table/tbody/tr[2]/td[6]/div/fieldset/div/div[@class='uif-boxLayout uif-horizontalBoxLayout clearfix']/button");
1220     //        Thread.sleep(2000);
1221     //
1222     //        // confirm that the input box containing the modified value is not present
1223     //        for (int second = 0;; second++) {
1224     //            if (second >= waitSeconds)
1225     //                jiraAwareFail(TIMEOUT_MESSAGE);
1226     //            try {
1227     //                if (!"selenium".equals(waitAndGetAttributeByName("list4[0].subList[0].field1", "value")))
1228     //                    break;
1229     //            } catch (Exception e) {}
1230     //            Thread.sleep(1000);
1231     //        }
1232     //
1233     //        // verify that the value has changed for the input box in the line that has replaced the deleted one
1234     //        assertNotSame("selenium", waitAndGetAttributeByName("list4[0].subList[0].field1", "value"));
1235     //    }
1236 
1237     protected void expandColapseByXpath(String clickLocator, String visibleLocator) throws InterruptedException {
1238         waitAndClickByXpath(clickLocator);
1239         waitIsVisibleByXpath(visibleLocator);
1240         waitAndClickByXpath(clickLocator);
1241         waitNotVisibleByXpath(visibleLocator);
1242     }
1243 
1244     protected String getDescriptionBase() {
1245         return this.getClass().toString().substring(this.getClass().toString().lastIndexOf(".") + 1,
1246                 this.getClass().toString().length()) +
1247                 "." + testMethodName + " description";
1248     }
1249 
1250     protected String getDescriptionUnique() {
1251         if (uniqueString == null) {
1252             uniqueString = AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomCharsNot9Digits();
1253         }
1254         return getDescriptionBase() + " " + uniqueString;
1255     }
1256 
1257     /**
1258      * {@inheritDoc}
1259      *
1260      * @return WebDriver
1261      */
1262     @Override
1263     protected WebDriver getDriver() {
1264         return driver;
1265     }
1266 
1267     /**
1268      * {@link org.openqa.selenium.WebDriver#getWindowHandles()}
1269      * @return
1270      */
1271     public String[] getAllWindowTitles() {
1272         return (String[]) driver.getWindowHandles().toArray();
1273     }
1274 
1275     protected String waitAndGetAttribute(By by, String attribute) throws InterruptedException {
1276         jiraAwareWaitFor(by, attribute);
1277 
1278         return findElement(by).getAttribute(attribute);
1279     }
1280 
1281     /**
1282      * Get value of any attribute by using element name
1283      *
1284      * @param name name of an element
1285      * @param attribute the name of an attribute whose value is to be retrieved
1286      */
1287     protected String waitAndGetAttributeByName(String name, String attribute) throws InterruptedException {
1288         return waitAndGetAttribute(By.name(name), attribute);
1289     }
1290 
1291     /**
1292      * Get value of any attribute by using element xpath
1293      *
1294      * @param locator locating mechanism of an element
1295      * @param attribute the name of an attribute whose value is to be retrieved
1296      */
1297     protected String waitAndGetAttributeByXpath(String locator, String attribute) throws InterruptedException {
1298         return waitAndGetAttribute(By.xpath(locator), attribute);
1299     }
1300 
1301     protected WebElement waitAndGetElementByAttributeValue(String attribute, String attributeValue) throws InterruptedException {
1302         return WebDriverUtils.waitAndGetElementByAttributeValue(driver, attribute, attributeValue, waitSeconds);
1303     }
1304 
1305     protected List<WebElement> waitAndGetElementsByAttributeValue(String attribute, String attributeValue) throws InterruptedException {
1306         // jenkins implies that implicitlyWait is worse than sleep loop for finding elements by 100+ test failures on the old sampleapp
1307         //        driver.manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
1308         //        driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
1309 
1310         driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
1311 
1312         boolean failed = false;
1313 
1314         for (int second = 0;; second++) {
1315             Thread.sleep(1000);
1316             if (second >= waitSeconds)
1317                 failed = true;
1318             try {
1319                 if (failed || (getElementsByAttributeValue(attribute, attributeValue) != null)) {
1320                     break;
1321                 }
1322             } catch (Exception e) {}
1323         }
1324 
1325         List<WebElement> elements = getElementsByAttributeValue(attribute, attributeValue);
1326         driver.manage().timeouts().implicitlyWait(WebDriverUtils.configuredImplicityWait(), TimeUnit.SECONDS);
1327         return elements;
1328     }
1329 
1330     protected String[] waitAndGetText(By by) throws InterruptedException {
1331         WebDriverUtils.waitFors(driver, WebDriverUtils.configuredImplicityWait(), by, this.getClass().toString());
1332         List<WebElement> found = findElements(by);
1333         String[] texts = new String[found.size()];
1334         int i = 0;
1335 
1336         for (WebElement element: found) {
1337             texts[i++] = element.getText();
1338         }
1339 
1340         if (texts.length == 0) {
1341             jiraAwareFail(by.toString());
1342         }
1343 
1344         return texts;
1345     }
1346 
1347 
1348     protected String getBaseUrlString() {
1349         return WebDriverUtils.getBaseUrlString();
1350     }
1351 
1352     protected int getCssCount(String selector) {
1353         return getCssCount(By.cssSelector(selector));
1354     }
1355 
1356     /**
1357      * Uses Selenium's findElements method which does not throw a test exception if not found.
1358      * @param by
1359      * @return
1360      */
1361     protected int getCssCount(By by) {
1362         return (findElements(by)).size();
1363     }
1364 
1365     protected String getDocStatus() {
1366         return findElement(By.xpath(DOC_STATUS_XPATH_2)).getText();
1367     }
1368 
1369     /**
1370      * Uses Selenium's findElements for getting the options (findElement for the select) method which does not throw a test exception if not found.
1371      * @param by
1372      * @return
1373      * @throws InterruptedException
1374      */
1375     protected String[] getSelectOptions(By by) throws InterruptedException {
1376         WebElement select1 = driver.findElement(by); // don't highlight
1377         List<WebElement> options = select1.findElements(By.tagName("option"));
1378         String[] optionValues = new String[options.size()];
1379         int counter = 0;
1380 
1381         for (WebElement option : options) {
1382             optionValues[counter] = option.getAttribute("value");
1383             counter++;
1384         }
1385 
1386         return optionValues;
1387     }
1388 
1389     protected String[] getSelectOptionsByName(String name) throws InterruptedException {
1390         return getSelectOptions(By.name(name));
1391     }
1392 
1393     protected String[] getSelectOptionsByXpath(String locator) throws InterruptedException {
1394         return getSelectOptions(By.xpath(locator));
1395     }
1396 
1397     /**
1398      *
1399      * @return sessionId
1400      */
1401     public String getSessionId() {
1402         return sessionId;
1403     }
1404 
1405     protected String getText(By by) throws InterruptedException {
1406         WebElement element = findElement(by);
1407         return element.getText();
1408     }
1409 
1410     protected String getTextByClassName(String className) throws InterruptedException {
1411         return getText(By.className(className));
1412     }
1413 
1414     protected String getTextById(String id) throws InterruptedException {
1415         return getText(By.id(id));
1416     }
1417 
1418     protected String getTextByName(String name) throws InterruptedException {
1419         return getText(By.name(name));
1420     }
1421 
1422     protected String getText(String locator) throws InterruptedException {
1423         return getText(By.cssSelector(locator));
1424     }
1425 
1426     protected String getTextByXpath(String locator) throws InterruptedException {
1427         return getText(By.xpath(locator));
1428     }
1429 
1430     protected String getTitle() {
1431         return driver.getTitle();
1432     }
1433 
1434     /**
1435      * "admin" by default.  Can be overridden using {@see WebDriverUtils#REMOTE_PUBLIC_USER_PROPERTY}
1436      * @return string
1437      */
1438     public String getUserName() {
1439         return user;
1440     }
1441 
1442     /**
1443      * <p>
1444      * Handles simple nested frame content; validates that a frame and nested frame exists before
1445      * switching to it.
1446      * </p><p>
1447      * Uses Selenium's findElements method which does not throw a test exception if not found.
1448      * </p>
1449      */
1450     protected void gotoNestedFrame() {
1451         driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
1452         driver.switchTo().defaultContent();
1453         final String iframeXpath = "//iframe";
1454 
1455         gotoIframeByXpath(iframeXpath);
1456 
1457         gotoIframeByXpath(iframeXpath);
1458 
1459         driver.manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
1460     }
1461 
1462     protected void gotoIframeById(final String iframeId) {
1463         if (driver.findElements(By.id(iframeId)).size() > 0) { // find elements so an exception isn't thrown if not found
1464             WebElement contentFrame = driver.findElement(By.id(iframeId)); // don't highlight
1465             driver.switchTo().frame(contentFrame);
1466         }
1467     }
1468     protected void gotoIframeByXpath(final String iframeXpath) {
1469         if (driver.findElements(By.xpath(iframeXpath)).size() > 0) {  // find elements so an exception isn't thrown if not found
1470             WebElement contentFrame = driver.findElement(By.xpath(iframeXpath)); // don't highlight
1471             driver.switchTo().frame(contentFrame);
1472         }
1473     }
1474 
1475     protected void gotoLightBox() {
1476         driver.switchTo().frame(driver.findElement(By.cssSelector(".fancybox-iframe")));
1477     }
1478 
1479     protected WebElement findButtonByText(String buttonText) {
1480         return WebDriverUtils.findButtonByText(driver, buttonText);
1481     }
1482 
1483     protected List<WebElement> findVisibleElements(By by) {
1484         List<WebElement> webElements = driver.findElements(by);
1485         List<WebElement> visibleWebElements = new LinkedList<WebElement>();
1486         for (WebElement webElement: webElements) {
1487             if (webElement.isDisplayed()) {
1488                 visibleWebElements.add(webElement);
1489             }
1490         }
1491 
1492         return visibleWebElements;
1493     }
1494 
1495     protected List<WebElement> findElements(By by) {
1496         List<WebElement> found = driver.findElements(by);
1497         return found;
1498     }
1499 
1500     protected List<WebElement> findElements(By by, WebElement element) {
1501         List<WebElement> found = element.findElements(by);
1502         return found;
1503     }
1504 
1505     protected void fireEvent(String name, String event) {
1506         ((JavascriptExecutor) driver).executeScript("var elements=document.getElementsByName(\"" + name + "\");" +
1507                 "for (var i = 0; i < elements.length; i++){" +
1508                 "elements[i]." + event + "();}");
1509     }
1510 
1511     protected void fireEvent(String name, String value, String event) {
1512         ((JavascriptExecutor) driver).executeScript("var elements=document.getElementsByName(\"" + name + "\");" +
1513                 "for (var i = 0; i < elements.length; i++){" +
1514                 "if(elements[i].value=='" + value + "')" +
1515                 "elements[i]." + event + "();}");
1516     }
1517 
1518     /**
1519      * {@link Actions#moveToElement(org.openqa.selenium.WebElement)}
1520      * @param name
1521      */
1522     public void fireMouseOverEventByName(String name) {
1523         this.fireMouseOverEvent(By.name(name));
1524     }
1525 
1526     /**
1527      * {@link Actions#moveToElement(org.openqa.selenium.WebElement)}
1528      * @param id
1529      */
1530     public void fireMouseOverEventById(String id) {
1531         this.fireMouseOverEvent(By.id(id));
1532     }
1533 
1534     /**
1535      * {@link Actions#moveToElement(org.openqa.selenium.WebElement)}
1536      * @param locator
1537      */
1538     public void fireMouseOverEventByXpath(String locator) {
1539         this.fireMouseOverEvent(By.xpath(locator));
1540     }
1541 
1542     /**
1543      * {@link Actions#moveToElement(org.openqa.selenium.WebElement)}
1544      * @param by
1545      */
1546     public void fireMouseOverEvent(By by) {
1547         Actions builder = new Actions(driver);
1548         Actions hover = builder.moveToElement(findElement(by));
1549         hover.perform();
1550     }
1551 
1552     protected boolean isChecked(By by) {
1553         return findElement(by).isSelected();
1554     }
1555 
1556     protected boolean isCheckedById(String id) {
1557         return isChecked(By.id(id));
1558     }
1559 
1560     protected boolean isCheckedByName(String name) {
1561         return isChecked(By.name(name));
1562     }
1563 
1564     protected boolean isCheckedByXpath(String locator) {
1565         return isChecked(By.xpath(locator));
1566     }
1567 
1568     protected boolean isEnabled(By by) {
1569         return findElement(by).isEnabled();
1570     }
1571 
1572     protected boolean isEnabledById(String id) {
1573         return isEnabled(By.id(id));
1574     }
1575 
1576     protected boolean isEnabledByName(String name) {
1577         return isEnabled(By.name(name));
1578     }
1579 
1580     protected boolean isEnabledByXpath(String locator) {
1581         return isEnabled(By.xpath(locator));
1582     }
1583 
1584     protected int howManyAreVisible(By by) throws InterruptedException {
1585         int count = 0;
1586         if (by == null) {
1587 
1588             return count;
1589         }
1590 
1591         List<WebElement> webElementsFound = driver.findElements(by);
1592         for (WebElement webElement: webElementsFound) {
1593             if (webElement.isDisplayed()) {
1594                 count++;
1595             }
1596         }
1597 
1598         return count;
1599     }
1600 
1601     /**
1602      * Uses Selenium's findElements method which does not throw a test exception if not found.
1603      * @param by
1604      * @return
1605      */
1606     protected boolean isElementPresent(By by) {
1607         return (driver.findElements(by)).size() > 0;
1608     }
1609 
1610     /**
1611      * Uses Selenium's findElements method which does not throw a test exception if not found.
1612      * @param locator
1613      * @return
1614      */
1615     protected boolean isElementPresent(String locator) {
1616         return (driver.findElements(By.cssSelector(locator))).size() > 0;
1617     }
1618 
1619     protected boolean isElementPresentById(String id) {
1620         return isElementPresent(By.id(id));
1621     }
1622 
1623     protected boolean isElementPresentByName(String name) {
1624         return isElementPresent(By.name(name));
1625     }
1626 
1627     protected boolean isElementPresentByXpath(String locator) {
1628         return isElementPresent(By.xpath(locator));
1629     }
1630 
1631     protected boolean isElementPresentByLinkText(String locator) {
1632         return isElementPresent(By.linkText(locator));
1633     }
1634 
1635     protected boolean isElementPresentByDataAttributeValue(String dataAttributeName, String dataAttributeValue) {
1636         return isElementPresent(By.cssSelector("[data-" + dataAttributeName +"='"+ dataAttributeValue +"']"));
1637     }
1638 
1639     protected boolean isNotVisible(By by) {
1640         return !(isVisible(by));
1641     }
1642 
1643     protected Boolean isTextPresent(String text) {
1644         return WebDriverUtils.isTextPresent(driver, driver.getPageSource(), text);
1645     }
1646 
1647     protected void jGrowl(String message) {
1648         WebDriverUtils.jGrowl(driver, jGrowlHeader, false, message);
1649     }
1650 
1651     /**
1652      * Sticky is used on fail, making a call to jGrowl(String) from this method will result
1653      * in an infinite loop if JGROWL_ERROR_FAILURE is true so please don't.
1654      */
1655     protected void jGrowlSticky(String message) {
1656         WebDriverUtils.jGrowl(driver, jGrowlHeader, true, message);
1657     }
1658 
1659     protected String multiValueResultCount() throws InterruptedException {
1660         WebElement dataTableInfo = waitAndGetElementByAttributeValue("class", "dataTables_info");
1661         String resultsCount = dataTableInfo.getText();
1662         resultsCount = resultsCount.substring(resultsCount.indexOf(" of ") + 4, resultsCount.indexOf(" entries")).trim();
1663         return resultsCount;
1664     }
1665 
1666     protected void open(String url) {
1667         driver.get(url);
1668     }
1669 
1670     public void screenshot() throws IOException {
1671         if (driver instanceof TakesScreenshot) {
1672             File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
1673             FileUtils.copyFile(scrFile, new File(System.getProperty("remote.driver.screenshot.dir", "." + File.separator),
1674                     System.getProperty("remote.driver.screenshot.filename", this.getClass().toString().replace("class ", "")
1675                             + "." + testMethodName + "-" + getDateTimeStampFormatted() + ".png")));
1676         }
1677     }
1678 
1679     public boolean screenshotSteps() {
1680         return "true".equals(System.getProperty("remote.driver.step.screenshot", "true"));
1681     }
1682 
1683     protected void selectFrameIframePortlet() {
1684         selectFrame(IFRAMEPORTLET_NAME);
1685     }
1686 
1687     protected void selectFrame(String locator) {
1688 
1689         if (IFRAMEPORTLET_NAME.equals(locator)) {
1690             gotoNestedFrame();
1691         } else {
1692             WebDriverUtils.selectFrameSafe(driver, locator);
1693         }
1694     }
1695 
1696     protected void selectTopFrame() {
1697         driver.switchTo().defaultContent();
1698     }
1699 
1700     protected void selectWindow(String locator) {
1701         driver.switchTo().window(locator);
1702     }
1703 
1704     protected void selectChildWindow() {
1705         selectWindow(driver.getWindowHandles().toArray()[1].toString());
1706     }
1707 
1708     protected void selectParentWindow() {
1709         selectWindow(driver.getWindowHandles().toArray()[0].toString());
1710     }
1711 
1712     protected void selectByXpath(String locator, String selectText) throws InterruptedException {
1713         select(By.xpath(locator), selectText);
1714     }
1715 
1716     protected void selectByName(String name, String selectText) throws InterruptedException {
1717         select(By.name(name), selectText);
1718     }
1719 
1720     /**
1721      * Uses Selenium's findElements method which does not throw a test exception if not found.
1722      * @param by
1723      * @param selectText
1724      * @throws InterruptedException
1725      */
1726     protected void select(By by, String selectText) throws InterruptedException {
1727 //        checkForIncidentReport(by.toString(), "trying to select text " + selectText); // I think a report will now be picked-up by the jiraAwareFail
1728         WebElement select1 = findElement(by);
1729         String name = select1.getAttribute("name");
1730         WebDriverUtils.jGrowl(getDriver(), "Select " + selectText, false, "Select " + selectText + " from " + name);
1731         List<WebElement> options = select1.findElements(By.tagName("option"));
1732 
1733         for (WebElement option : options) {
1734             if (option.getText().equals(selectText)) {
1735                 option.click();
1736 //                break; // seems to be causing a hang?
1737             }
1738         }
1739     }
1740 
1741     /**
1742      * If a window contains the given title switchTo it.
1743      * @param title
1744      */
1745     public void switchToWindow(String title) {
1746         Set<String> windows = driver.getWindowHandles();
1747 
1748         for (String window : windows) {
1749             driver.switchTo().window(window);
1750             if (driver.getTitle().contains(title)) {
1751                 return;
1752             }
1753         }
1754     }
1755 
1756     // TODO delete after AddingNameSpaceAbstractSmokeTestBase migration
1757     protected void testAddingNamespace() throws Exception {
1758         testAddingNamespace(this);
1759     }
1760 
1761     // TODO move method to AddingNameSpaceAbstractSmokeTestBase after locators are extracted
1762     protected void testAddingNamespace(JiraAwareFailable failable) throws Exception {
1763         selectFrameIframePortlet();
1764         waitAndCreateNew();
1765         waitForElementPresentByXpath(SAVE_XPATH_2, "save button does not exist on the page");
1766 
1767         //Enter details for Namespace.
1768         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Adding PEANUTS");
1769         waitAndTypeByXpath("//*[@id='document.documentHeader.explanation']", "I want to add PEANUTS to test KIM");
1770         waitAndTypeByXpath(DOC_CODE_XPATH, "PEANUTS");
1771         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.name']", "The Peanuts Gang");
1772         checkByXpath("//input[@id='document.newMaintainableObject.active']");
1773         waitAndClickByXpath(SAVE_XPATH_2);
1774         waitForElementPresentByXpath(SAVE_SUCCESSFUL_XPATH, "Document is not saved successfully");
1775 
1776         //checks it is saved and initiator is admin.
1777         assertEquals(DOC_STATUS_SAVED, findElement(By.xpath("//table[@class='headerinfo']/tbody/tr[1]/td[2]")).getText());
1778         assertEquals("admin", findElement(By.xpath("//table[@class='headerinfo']/tbody/tr[2]/td[1]/a")).getText());
1779     }
1780 
1781     protected void testAddingBrownGroup() throws Exception {
1782         selectFrameIframePortlet();
1783         waitAndCreateNew();
1784         String docId = waitForDocId();
1785         String random = RandomStringUtils.randomNumeric(4);
1786         String organizationDocumentNumber = "ORD" + random;
1787         String groupDescription = "GD" + random;
1788         String groupName = "BrownGroup " + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
1789         String nameSpace = "KR-IDM";
1790         String today = getDateToday();
1791         Calendar nextYearCal = Calendar.getInstance();
1792         nextYearCal.add(Calendar.YEAR, 1);
1793         SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
1794         String nextYear = sdf.format(nextYearCal.getTime());
1795 
1796         //Enter details for BrownGroup.
1797         waitAndTypeByName("document.documentHeader.documentDescription", "Adding Brown Group");
1798         waitAndTypeByName("document.documentHeader.explanation", "I want to add Brown Group to test KIM");
1799         waitAndTypeByName("document.documentHeader.organizationDocumentNumber", organizationDocumentNumber);
1800         selectOptionByName("document.groupNamespace", nameSpace);
1801         waitAndTypeByName("document.groupName", groupName);
1802         waitAndTypeByName("document.groupDescription", groupDescription);
1803 
1804         // Add Ad hoc Recipient
1805         addAdHocRecipientsPerson(new String[]{"dev1", "F"}); // "One, Developer"
1806 
1807         // Add Ad hoc Workgroup
1808         waitAndClickByName("methodToCall.performLookup.(!!org.kuali.rice.kim.impl.group.GroupBo!!).(((namespaceCode:newAdHocRouteWorkgroup.recipientNamespaceCode,name:newAdHocRouteWorkgroup.recipientName))).((`newAdHocRouteWorkgroup.recipientNamespaceCode:namespaceCode,newAdHocRouteWorkgroup.recipientName:name`)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;;::::).anchor");
1809         waitForElementPresentByXpath(SEARCH_XPATH);
1810         selectOptionByName("namespaceCode", nameSpace);
1811         waitAndClickSearch();
1812         Thread.sleep(2000);
1813         String adHocWrkGrp = null;
1814         if (isTextPresent("No values match this search.")) {
1815             waitAndClickByXpath(CANCEL3_XPATH);
1816         } else {
1817             waitAndClickReturnValue();
1818             waitAndClickByName("methodToCall.insertAdHocRouteWorkgroup");
1819             adHocWrkGrp = findElement(By.name("adHocRouteWorkgroup[0].recipientName")).getAttribute("value");
1820         }
1821 
1822         checkByName("document.active");
1823         waitAndClickByXpath(SAVE_XPATH_2);
1824         waitForTextPresent("Document was successfully saved.");
1825 
1826         //checks it is saved and initiator is admin.
1827         assertEquals(DOC_STATUS_SAVED, findElement(By.xpath("//table[@class='headerinfo']/tbody/tr[1]/td[2]")).getText());
1828         assertEquals("admin", findElement(By.xpath("//table[@class='headerinfo']/tbody/tr[2]/td[1]/a")).getText());
1829         waitAndClickByName("methodToCall.performLookup.(!!org.kuali.rice.kim.impl.identity.PersonImpl!!).(((principalId:member.memberId,principalName:member.memberName))).((``)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;;::::).anchorAssignees");
1830         waitAndClickSearch();
1831         String adHocPerson = waitForElementPresentByXpath("//table[@id='row']/tbody/tr/td[2]/a").getText();
1832         waitAndClickReturnValue();
1833         waitAndClickByName("methodToCall.addMember.anchorAssignees");
1834         waitAndClickSave();
1835         waitAndClickSubmit();
1836         waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
1837         selectTopFrame();
1838 
1839         // Verify Document Overview info
1840         docSearch(docId);
1841         waitAndClickByLinkText(docId);
1842         switchToWindow("Kuali :: Group");
1843         assertTextPresent(new String[]{"Adding Brown Group", "I want to add Brown Group to test KIM", organizationDocumentNumber});
1844         waitAndClickByName("methodToCall.close");
1845 
1846         waitAndClickByLinkText("Administration");
1847         waitAndClickByLinkText("Group");
1848         selectFrameIframePortlet();
1849         waitAndTypeByName("name", groupName);
1850         waitAndClickSearch();
1851         waitForElementPresent(By.linkText(groupName), docId + " with groupName "+ groupName + " not present!");
1852         waitAndClickByLinkText("edit");
1853         waitAndClickByName("methodToCall.showAllTabs");
1854         assertTextPresent(new String[]{adHocPerson, groupDescription, nameSpace, groupName});
1855     }
1856 
1857     protected String getDateTimeStampFormatted() {
1858         Date now = Calendar.getInstance().getTime();
1859         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
1860         return sdf.format(now);
1861     }
1862 
1863     protected String getDateToday() {
1864         Date now = Calendar.getInstance().getTime();
1865         SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
1866         return sdf.format(now);
1867     }
1868 
1869     protected String getDateTomorrow() {
1870         Calendar now = Calendar.getInstance();
1871         now.add(Calendar.DATE, 1);
1872         SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
1873         return sdf.format(now.getTime());
1874     }
1875 
1876     protected void testAttributeDefinitionLookUp() throws Exception {
1877         waitForPageToLoad();
1878         selectFrameIframePortlet();
1879         waitAndClickByXpath("//button[contains(.,'earch')]");
1880         Thread.sleep(3000);
1881         waitForPageToLoad();
1882         findElement(By.tagName("body")).getText().contains("Actions"); // there are no actions, but the header is the only unique text from searching
1883         waitAndClickByLinkText("1000");
1884         waitForPageToLoad();
1885         findElement(By.tagName("body")).getText().contains("Attribute Inquiry");
1886         findElement(By.tagName("body")).getText().contains("KRMS Attributes");
1887         findElement(By.tagName("body")).getText().contains("Attribute Label");
1888         findElement(By.tagName("body")).getText().contains("1000");
1889         findElement(By.tagName("body")).getText().contains("peopleFlowId");
1890         findElement(By.tagName("body")).getText().contains("KR-RULE");
1891         findElement(By.tagName("body")).getText().contains("PeopleFlow");
1892 
1893         // selectFrame("name=fancybox-frame1343151577256"); // TODO parse source to get name
1894         // jiraAwareWaitAndClick("css=button:contains(Close)"); // looks lower case, but is upper
1895         // Thread.sleep(500);
1896         // jiraAwareWaitAndClick("css=button:contains(cancel)");
1897         // AttributeDefinition's don't have actions (yet)
1898         // jiraAwareWaitAndClick("id=u80");
1899         // waitForPageToLoad();
1900         // jiraAwareWaitAndClick("id=u86");
1901         // waitForPageToLoad();
1902         // selectWindow("null");
1903         // jiraAwareWaitAndClick("xpath=(//input[@name='imageField'])[2]");
1904         // waitForPageToLoad();
1905         passed();
1906     }
1907 
1908     protected void testCancelConfirmation() throws InterruptedException {
1909         waitAndCancelConfirmation();
1910         passed();
1911     }
1912 
1913     protected void testConfigParamaterBlanketApprove() throws Exception {
1914         selectFrameIframePortlet();
1915         waitAndCreateNew();
1916         String docId = waitForDocId();
1917         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Validation Test Parameter ");
1918         assertBlanketApproveButtonsPresent();
1919         assertEquals("", getTextByName(CANCEL_NAME));
1920         selectByXpath("//select[@id='document.newMaintainableObject.namespaceCode']", "KR-NS - Kuali Nervous System");
1921         String componentLookUp = "//input[@name='methodToCall.performLookup.(!!org.kuali.rice.coreservice.impl.component.ComponentBo!!).(((code:document.newMaintainableObject.componentCode,namespaceCode:document.newMaintainableObject.namespaceCode,))).((`document.newMaintainableObject.componentCode:code,document.newMaintainableObject.namespaceCode:namespaceCode,`)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;"
1922                 + getBaseUrlString() + "/kr/lookup.do;::::).anchor4']";
1923         waitAndClickByXpath(componentLookUp);
1924         waitAndClickSearch();
1925         waitAndClickReturnValue();
1926         String dtsTwo = AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
1927         String parameterName = "ValidationTestParameter" + dtsTwo;
1928         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.name']", parameterName);
1929         waitAndTypeByXpath("//textarea[@id='document.newMaintainableObject.description']",
1930                 "Validation Test Parameter Description" + dtsTwo);
1931         selectByXpath("//select[@id='document.newMaintainableObject.parameterTypeCode']", "Document Validation");
1932         waitAndClickByXpath("//input[@id='document.newMaintainableObject.evaluationOperatorCodeAllowed']");
1933         waitForPageToLoad();
1934         blanketApproveTest(docId);
1935     }
1936 
1937     protected void testCreateNewAgenda() throws Exception {
1938         selectFrameIframePortlet();
1939         selectByName("document.newMaintainableObject.dataObject.namespace", "Kuali Rules Test");
1940         String agendaName = "Agenda Date :" + Calendar.getInstance().getTime().toString();
1941         waitAndTypeByName("document.newMaintainableObject.dataObject.agenda.name", "Agenda " + agendaName);
1942         fireEvent("document.newMaintainableObject.dataObject.contextName", "focus");
1943         waitAndTypeByName("document.newMaintainableObject.dataObject.contextName", "Context1");
1944         fireEvent("document.newMaintainableObject.dataObject.contextName", "blur");
1945         Thread.sleep(1000);
1946         // extra focus and blur to work around KULRICE-11534 Create New Agenda requires two blur events to fully render Type when Context is typed in (first renders label, second renders select)
1947         fireEvent("document.newMaintainableObject.dataObject.contextName", "focus");
1948         fireEvent("document.newMaintainableObject.dataObject.contextName", "blur");
1949         waitForElementPresentByName("document.newMaintainableObject.dataObject.agenda.typeId");
1950         selectByName("document.newMaintainableObject.dataObject.agenda.typeId", "Campus Agenda");
1951         waitForElementPresentByName("document.newMaintainableObject.dataObject.customAttributesMap[Campus]");
1952         waitAndTypeByName("document.newMaintainableObject.dataObject.customAttributesMap[Campus]", "BL");
1953         waitAndClickButtonByText("submit");
1954         assertTextPresent(new String[] {"Document was successfully submitted.", "ENROUTE"});
1955         passed();
1956     }
1957 
1958     protected void testCreateDocType() throws Exception {
1959         selectFrameIframePortlet();
1960         waitAndCreateNew();
1961         assertElementPresentByXpath("//*[@name='methodToCall.route' and @alt='submit']","save button does not exist on the page");
1962 
1963         //waitForElementPresentByXpath(DOC_ID_XPATH);
1964         //String docId = findElement(By.xpath(DOC_ID_XPATH)).getText();
1965         String docId = waitForDocId();
1966         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Creating new Document Type");
1967         String parentDocType = "//input[@name='methodToCall.performLookup.(!!org.kuali.rice.kew.doctype.bo.DocumentType!!).(((name:document.newMaintainableObject.parentDocType.name,documentTypeId:document.newMaintainableObject.docTypeParentId,))).((`document.newMaintainableObject.parentDocType.name:name,`)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;"
1968                 + getBaseUrlString() + "/kr/lookup.do;::::).anchor4']";
1969         waitAndClickByXpath(parentDocType);
1970         waitForPageToLoad();
1971         Thread.sleep(2000);
1972         waitAndClickSearch();
1973         waitAndClickReturnValue();
1974         String docTypeName = "TestDocType" + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
1975         waitForElementPresentByXpath("//input[@id='document.newMaintainableObject.name']");
1976         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.name']", docTypeName);
1977         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.unresolvedDocHandlerUrl']","${kr.url}/maintenance.do?methodToCall=docHandler");
1978 
1979         //waitAndTypeByXpath("//input[@id='document.newMaintainableObject.actualNotificationFromAddress']", "NFA");
1980         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.label']", "Label for " + docTypeName);
1981         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.unresolvedHelpDefinitionUrl']","default.htm?turl=WordDocuments%2Fdocumenttype.htm");
1982         waitAndClickByXpath("//*[@name='methodToCall.route' and @alt='submit']");
1983         checkForIncidentReport();
1984         waitForPageToLoad();
1985         driver.switchTo().defaultContent();
1986         waitAndClickDocSearchTitle();
1987         waitForPageToLoad();
1988         selectFrameIframePortlet();
1989         waitAndClickSearch();
1990         Thread.sleep(2000);
1991         assertEquals(docId, findElement(By.xpath(DOC_ID_XPATH_2)).getText());
1992     }
1993 
1994     protected String testCreateNew() throws InterruptedException {
1995         selectFrameIframePortlet();
1996         waitAndCreateNew();
1997         String docId = verifyDocInitiated();
1998         createNewEnterDetails();
1999         return docId;
2000     }
2001 
2002     protected void testCreateNewCancel() throws Exception {
2003         selectFrameIframePortlet();
2004         waitAndCreateNew();
2005         String docId = verifyDocInitiated();
2006         createNewEnterDetails();
2007         testCancelConfirmation();
2008         assertDocSearchNoResults(docId);
2009     }
2010 
2011     private String verifyDocInitiated() throws InterruptedException {
2012         String docId = waitForDocId();
2013         assertEquals("INITIATED", waitForDocStatus());
2014         assertEquals(getUserName(), waitForDocInitiator());
2015         return docId;
2016     }
2017 
2018     protected List<String> testCreateNewParameter(String docId, String parameterName) throws Exception {
2019         waitForPageToLoad();
2020         docId = waitForDocId();
2021         //Enter details for Parameter.
2022         waitAndTypeByName("document.documentHeader.documentDescription", "Adding Test Parameter");
2023         selectOptionByName("document.newMaintainableObject.namespaceCode", "KR-WKFLW");
2024         waitAndTypeByName("document.newMaintainableObject.componentCode", "ActionList");
2025         waitAndTypeByName("document.newMaintainableObject.applicationId", "KUALI");
2026         parameterName = "TestIndicator" + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
2027         waitAndTypeByName("document.newMaintainableObject.name", parameterName);
2028         waitAndTypeByName("document.newMaintainableObject.value", "Y");
2029         waitAndTypeByName("document.newMaintainableObject.description", "for testing");
2030         selectOptionByName("document.newMaintainableObject.parameterTypeCode", "HELP");
2031         waitAndClickByXpath("//input[@name='document.newMaintainableObject.evaluationOperatorCode' and @value='A']");
2032         waitAndClickSave();
2033         waitAndClickSubmit();
2034         waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
2035 
2036 
2037         assertDocSearch(docId, DOC_STATUS_FINAL);
2038         selectTopFrame();
2039         List<String> params = new ArrayList<String>();
2040         params.add(docId);
2041         params.add(parameterName);
2042 
2043         return params;
2044     }
2045 
2046     protected List<String> testCreateNewParameterType(String docId, String parameterType, String parameterCode)throws Exception {
2047         waitForPageToLoad();
2048         docId = waitForDocId();
2049 
2050         //Enter details for Parameter.
2051         waitAndTypeByName("document.documentHeader.documentDescription", "Adding Test Parameter Type");
2052         parameterCode = RandomStringUtils.randomAlphabetic(4).toLowerCase();
2053         waitAndTypeByName("document.newMaintainableObject.code", parameterCode);
2054         parameterType = "testing " + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
2055         waitAndTypeByName("document.newMaintainableObject.name", parameterType);
2056         waitAndClickSave();
2057         waitAndClickSubmit();
2058         waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
2059         assertDocSearch(docId, DOC_STATUS_FINAL);
2060         selectTopFrame();
2061         List<String> params = new ArrayList<String>();
2062         params.add(docId);
2063         params.add(parameterType);
2064         params.add(parameterCode);
2065 
2066         return params;
2067     }
2068 
2069     protected void testCreateNewSearchReturnValueCancelConfirmation() throws InterruptedException, Exception {
2070         selectFrameIframePortlet();
2071         waitAndCreateNew();
2072         waitAndClickSearch2();
2073         waitAndClickReturnValue();
2074         waitAndCancelConfirmation();
2075         passed();
2076     }
2077 
2078     protected List<String> testCopyParameter(String docId, String parameterName) throws Exception {
2079         selectFrameIframePortlet();
2080         waitAndClickCopy();
2081         waitForPageToLoad();
2082         docId = waitForDocId();
2083         waitAndTypeByName("document.documentHeader.documentDescription", "Copying Test Parameter");
2084         selectOptionByName("document.newMaintainableObject.namespaceCode", "KR-WKFLW");
2085         waitAndTypeByName("document.newMaintainableObject.componentCode", "ActionList");
2086         waitAndTypeByName("document.newMaintainableObject.applicationId", "KUALI");
2087         parameterName = "TestIndicator" + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
2088         waitAndTypeByName("document.newMaintainableObject.name", parameterName);
2089         waitAndClickSave();
2090         waitAndClickSubmit();
2091         waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
2092         assertDocSearch(docId, DOC_STATUS_FINAL);
2093         selectTopFrame();
2094         List<String> params = new ArrayList<String>();
2095         params.add(docId);
2096         params.add(parameterName);
2097 
2098         return params;
2099     }
2100 
2101     protected List<String> testCopyParameterType(String docId, String parameterType, String parameterCode) throws Exception {
2102         selectFrameIframePortlet();
2103         waitAndClickCopy();
2104         waitForPageToLoad();
2105         docId = waitForDocId();
2106         waitAndTypeByName("document.documentHeader.documentDescription", "Copying Test Parameter");
2107         parameterCode = RandomStringUtils.randomAlphabetic(4).toLowerCase();
2108         waitAndTypeByName("document.newMaintainableObject.code", parameterCode);
2109         clearTextByName("document.newMaintainableObject.name");
2110         parameterType = "testing " + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
2111         waitAndTypeByName("document.newMaintainableObject.name", parameterType);
2112         waitAndClickSave();
2113         waitAndClickSubmit();
2114         waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
2115         assertDocSearch(docId, DOC_STATUS_FINAL);
2116         selectTopFrame();
2117         List<String> params = new ArrayList<String>();
2118         params.add(docId);
2119         params.add(parameterType);
2120         params.add(parameterCode);
2121 
2122         return params;
2123     }
2124 
2125 
2126     protected void testDocTypeLookup() throws Exception {
2127         selectFrameIframePortlet();
2128         waitAndClickByXpath("//input[@title='Search Parent Name']");
2129         waitAndClickByXpath(SAVE_XPATH_3);
2130         waitAndClickByXpath("//table[@id='row']/tbody/tr[contains(td[3],'RiceDocument')]/td[1]/a");
2131         waitAndClickByXpath(SAVE_XPATH_3);
2132         assertEquals("RiceDocument", getTextByXpath("//table[@id='row']/tbody/tr/td[4]/a"));
2133         waitAndClickByName("methodToCall.clearValues");
2134         waitAndTypeByName("name", "Kuali*D");
2135         waitAndClickByXpath(SAVE_XPATH_3);
2136         assertElementPresentByXpath("//table[@id='row']/tbody/tr[contains(td[3], 'KualiDocument')]");
2137         String docIdOld = getTextByXpath("//table[@id='row']/tbody/tr[contains(td[3], 'KualiDocument')]/td[2]/a");
2138         waitAndClickByName("methodToCall.clearValues");
2139         waitAndTypeByName("label", "KualiDocument");
2140         waitAndClickByXpath(SAVE_XPATH_3);
2141         assertElementPresentByXpath("//table[@id='row']/tbody/tr[contains(td[5], 'KualiDocument')]");
2142         waitAndClickByName("methodToCall.clearValues");
2143         waitAndTypeByName("documentTypeId", docIdOld);
2144         waitAndClickByXpath(SAVE_XPATH_3);
2145         assertElementPresentByXpath("//table[@id='row']/tbody/tr[contains(td[2], '" + docIdOld + "')]");
2146     }
2147 
2148 
2149     protected List<String> testEditParameterType(String docId, String parameterType, String parameterCode) throws Exception {
2150         selectFrameIframePortlet();
2151         waitAndClickEdit();
2152         waitForPageToLoad();
2153         docId = waitForDocId();
2154         waitAndTypeByName("document.documentHeader.documentDescription", "Editing Test Parameter");
2155         clearTextByName("document.newMaintainableObject.name");
2156         parameterType = "testing " + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
2157         waitAndTypeByName("document.newMaintainableObject.name", parameterType);
2158         waitAndClickSave();
2159         waitAndClickSubmit();
2160         waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
2161         assertDocSearch(docId, DOC_STATUS_FINAL);
2162         selectTopFrame();
2163         List<String> params = new ArrayList<String>();
2164         params.add(docId);
2165         params.add(parameterType);
2166         params.add(parameterCode);
2167 
2168         return params;
2169     }
2170 
2171     protected List<String> testEditParameter(String docId, String parameterName) throws Exception {
2172         selectFrameIframePortlet();
2173         waitAndClickEdit();
2174         waitForPageToLoad();
2175         docId = waitForDocId();
2176         waitAndTypeByName("document.documentHeader.documentDescription", "Editing Test Parameter");
2177         clearTextByName("document.newMaintainableObject.value");
2178         waitAndTypeByName("document.newMaintainableObject.value", "N");
2179         waitAndClickSave();
2180         waitAndClickSubmit();
2181         waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
2182         assertDocSearch(docId, DOC_STATUS_FINAL);
2183         selectTopFrame();
2184         List<String> params = new ArrayList<String>();
2185         params.add(docId);
2186         params.add(parameterName);
2187         return params;
2188     }
2189 
2190     protected void testEditRouteRulesDelegation() throws Exception {
2191         waitForPageToLoad();
2192         Thread.sleep(3000);
2193         assertEquals("Kuali Portal Index", getTitle());
2194         selectFrameIframePortlet();
2195         waitAndClickSearch();
2196         waitAndClickEdit();
2197         waitForPageToLoad();
2198         Thread.sleep(3000);
2199         assertTrue(isElementPresentByName(CANCEL_NAME));
2200         waitAndClickCancel();
2201         waitAndClickByName("methodToCall.processAnswer.button0");
2202         waitForPageToLoad();
2203         passed();
2204     }
2205 
2206     protected void testFiscalOfficerInfoMaintenanceNew() throws Exception {
2207         selectFrameIframePortlet();
2208         checkForIncidentReport();
2209         String docId = getTextByXpath("//*[@id='u13_control']");
2210         waitAndTypeByXpath("//input[@name='document.documentHeader.documentDescription']", "New FO Doc");
2211         waitAndTypeByXpath("//input[@name='document.newMaintainableObject.dataObject.id']", "5");
2212         waitAndTypeByXpath("//input[@name='document.newMaintainableObject.dataObject.userName']", "Jigar");
2213         waitAndClickByXpath("//button[@id='usave']");
2214         Integer docIdInt = Integer.valueOf(docId).intValue();
2215         waitAndClickActionList();
2216         selectFrameIframePortlet();
2217 
2218         if(isElementPresentByLinkText("Last")){
2219             waitAndClickByLinkText("Last");
2220             waitAndClickByLinkText(docIdInt.toString());
2221         } else {
2222             waitAndClickByLinkText(docIdInt.toString());
2223         }
2224 
2225         //      ------------------------------- Not working in code when click docId link in list--------------------------
2226         //Thread.sleep(5000);
2227         //String[] windowTitles = getAllWindowTitles();
2228         //selectWindow(windowTitles[1]);
2229         //windowFocus();
2230         //assertEquals(windowTitles[1], getTitle());
2231         //checkForIncidentReport("Action List Id link opened window.", "https://jira.kuali.org/browse/KULRICE-9062 Action list id links result in 404 or NPE");
2232 
2233         //------submit-----//
2234         //selectFrame("relative=up");
2235         //waitAndClick("//button[@value='submit']");
2236         //waitForPageToLoad50000();
2237         //close();
2238         //------submit over---//
2239 
2240         //----step 2----//
2241         //selectWindow("null");
2242         //windowFocus();
2243         //waitAndClick("//img[@alt='doc search']");
2244         //waitForPageToLoad50000();
2245         //assertEquals(windowTitles[0], getTitle());
2246         //selectFrame("iframeportlet");
2247         //waitAndClick(SEARCH_XPATH);
2248         //waitForPageToLoad50000();
2249         //----step 2 over ----//
2250 
2251         //-----Step 3 verifies that doc is final-------//
2252         //assertEquals("FINAL", getText("//table[@id='row']/tbody/tr[1]/td[4]"));
2253         //selectFrame("relative=up");
2254         //waitAndClick("link=Main Menu");
2255         //waitForPageToLoad50000();
2256         //assertEquals(windowTitles[0], getTitle());
2257         //-----Step 3 verified that doc is final -------
2258     }
2259 
2260     protected void testIdentityGroupBlanketApprove() throws Exception {
2261         selectFrameIframePortlet();
2262         waitAndCreateNew();
2263         String docId = waitForDocId();
2264         String dtsTwo = AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomCharsNot9Digits();
2265         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Validation Test Group " + dtsTwo);
2266         assertBlanketApproveButtonsPresent();
2267         selectByXpath("//select[@id='document.groupNamespace']", LABEL_KUALI_KUALI_SYSTEMS);
2268         waitAndTypeByXpath("//input[@id='document.groupName']", "Validation Test Group1 " + dtsTwo);
2269         waitAndClickByName(
2270                 "methodToCall.performLookup.(!!org.kuali.rice.kim.impl.identity.PersonImpl!!).(((principalId:member.memberId,principalName:member.memberName))).((``)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;;::::).anchorAssignees");
2271         waitAndClickSearch();
2272         waitAndClickReturnValue();
2273         waitAndClickByName("methodToCall.addMember.anchorAssignees");
2274         waitForPageToLoad();
2275         blanketApproveTest(docId);
2276     }
2277 
2278     protected void testIdentityPermissionBlanketApprove() throws Exception {
2279         selectFrameIframePortlet();
2280         waitAndCreateNew();
2281         String docId = waitForDocId();
2282         String dtsTwo = AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomCharsNot9Digits();
2283         waitAndTypeByXpath("//input[@name='document.documentHeader.documentDescription']",
2284                 "Validation Test Permission " + dtsTwo);
2285         assertBlanketApproveButtonsPresent();
2286         waitAndTypeByXpath("//input[@name='document.documentHeader.organizationDocumentNumber']", "10012");
2287         selectByXpath("//select[@name='document.newMaintainableObject.namespaceCode']", LABEL_KUALI_KUALI_SYSTEMS);
2288         selectByXpath("//select[@name='document.newMaintainableObject.templateId']", LABEL_KUALI_DEFAULT);
2289         waitAndTypeByXpath("//input[@name='document.newMaintainableObject.name']",
2290                 "ValidationTestPermission" + dtsTwo);
2291         blanketApproveTest(docId);
2292     }
2293 
2294     protected void testIdentityPersonBlanketApprove() throws Exception {
2295         selectFrameIframePortlet();
2296         waitAndCreateNew();
2297         String docId = waitForDocId();
2298         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Validation Test Person");
2299         assertBlanketApproveButtonsPresent();
2300         waitAndTypeByXpath("//input[@id='document.principalName']", "principal" + RandomStringUtils.randomAlphabetic(3).toLowerCase());
2301         selectByName("newAffln.affiliationTypeCode", "Affiliate");
2302         selectByName("newAffln.campusCode", "BX - BLGTN OFF CAMPUS");
2303         selectByName("newAffln.campusCode", "BL - BLOOMINGTON");
2304         assertElementPresentByName("newAffln.dflt");
2305         waitAndClickByName("newAffln.dflt");
2306         waitAndClickByName("methodToCall.addAffln.anchor");
2307         waitAndClickByName("methodToCall.toggleTab.tabContact");
2308         selectByName("newName.namePrefix", "Mr");
2309         waitAndTypeByName("newName.firstName", "First");
2310         waitAndTypeByName("newName.lastName", "Last");
2311         selectByName("newName.nameSuffix", "Mr");
2312         waitAndClickByName("newName.dflt");
2313         waitAndClickByName("methodToCall.addName.anchor");
2314         waitForPageToLoad();
2315         blanketApproveTest(docId);
2316     }
2317 
2318     protected void testIdentityResponsibilityBlanketApprove() throws Exception {
2319         selectFrameIframePortlet();
2320         waitAndCreateNew();
2321         String docId = waitForDocId();
2322         String dtsTwo = AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomCharsNot9Digits();
2323         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Validation Test Responsibility " + dtsTwo);
2324         assertBlanketApproveButtonsPresent();
2325         selectByXpath("//select[@id='document.newMaintainableObject.namespaceCode']", LABEL_KUALI_KUALI_SYSTEMS);
2326         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.name']",
2327                 "Validation Test Responsibility " + dtsTwo);
2328         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.documentTypeName']", "Test " + dtsTwo);
2329         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.routeNodeName']", "Test " + dtsTwo);
2330         waitAndClickByXpath("//input[@id='document.newMaintainableObject.actionDetailsAtRoleMemberLevel']");
2331         waitAndClickByXpath("//input[@id='document.newMaintainableObject.required']");
2332         blanketApproveTest(docId);
2333     }
2334 
2335     protected void testIdentityRoleBlanketApprove() throws Exception {
2336         selectFrameIframePortlet();
2337         waitAndCreateNew();
2338         waitAndClickByXpath(SEARCH_XPATH, "No search button to click.");
2339         waitAndClickReturnValue();
2340         String docId = waitForDocId();
2341         String dtsTwo = AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomCharsNot9Digits();
2342         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Validation Test Role " + dtsTwo);
2343         assertBlanketApproveButtonsPresent();
2344         selectByXpath("//select[@id='document.roleNamespace']", LABEL_KUALI_KUALI_SYSTEMS);
2345         waitAndTypeByXpath("//input[@id='document.roleName']", "Validation Test Role " + dtsTwo,
2346                 "No Role Name input to type in.");
2347         waitAndClickByName(
2348                 "methodToCall.performLookup.(!!org.kuali.rice.kim.impl.identity.PersonImpl!!).(((principalId:member.memberId,principalName:member.memberName))).((``)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;;::::).anchorAssignees");
2349         waitAndClickByXpath(SEARCH_XPATH, "No search button to click.");
2350         waitAndClickReturnValue();
2351         waitAndClickByName("methodToCall.addMember.anchorAssignees");
2352         waitForPageToLoad();
2353         blanketApproveTest(docId);
2354     }
2355 
2356     protected void testLocationCampusBlanketApprove() throws Exception {
2357         selectFrameIframePortlet();
2358         waitAndCreateNew();
2359         String docId = waitForDocId();
2360         String twoLetters = RandomStringUtils.randomAlphabetic(2);
2361         waitAndTypeByName("document.documentHeader.documentDescription", "Validation Test Campus " + twoLetters);
2362         assertBlanketApproveButtonsPresent();
2363         waitAndTypeByName("document.newMaintainableObject.code", RandomStringUtils.randomAlphabetic(2));
2364         waitAndTypeByName("document.newMaintainableObject.name", "Validation Test Campus" + AutomatedFunctionalTestUtils
2365                 .createUniqueDtsPlusTwoRandomChars());
2366         waitAndTypeByName("document.newMaintainableObject.shortName", "VTC " + twoLetters);
2367         selectByName("document.newMaintainableObject.campusTypeCode", "B - BOTH");
2368         blanketApproveTest(docId);
2369     }
2370 
2371     protected void testLocationCountryBlanketApprove() throws InterruptedException {
2372         selectFrameIframePortlet();
2373         String randomCode = searchForAvailableCode(2);
2374 
2375         waitAndCreateNew();
2376         String docId = waitForDocId();
2377         String countryName = "Validation Test Country " + randomCode + " " + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomCharsNot9Digits();
2378         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, countryName);
2379         waitAndTypeByXpath(DOC_CODE_XPATH, randomCode);
2380         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.name']", countryName);
2381         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.alternateCode']", "V" + randomCode);
2382 
2383         finishBlanketApprovalTest(docId);
2384     }
2385 
2386     private void finishBlanketApprovalTest(String docId) throws InterruptedException {
2387         assertBlanketApproveButtonsPresent();
2388         blanketApproveCheck();
2389         if (!hasDocError("same primary key already exists")) { // don't fail as to still have the same key after 25 sequential attempts we've created many today already
2390             blanketApproveAssert(docId);
2391         }
2392     }
2393 
2394     protected void testLocationCountyBlanketApprove() throws Exception {
2395         selectFrameIframePortlet();
2396         waitAndCreateNew();
2397         String docId = waitForDocId();
2398         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Validation Test County");
2399         assertBlanketApproveButtonsPresent();
2400         String countryLookUp = "//input[@name='methodToCall.performLookup.(!!org.kuali.rice.location.impl.country.CountryBo!!).(((code:document.newMaintainableObject.countryCode,))).((`document.newMaintainableObject.countryCode:code,`)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;"
2401                 + getBaseUrlString() + "/kr/lookup.do;::::).anchor4']";
2402         waitAndClickByXpath(countryLookUp);
2403         waitAndTypeByName("code", "US");
2404         waitAndClickSearch();
2405         waitAndClickReturnValue();
2406         waitAndTypeByXpath(DOC_CODE_XPATH, RandomStringUtils.randomAlphabetic(2).toUpperCase());
2407         String stateLookUp = "//input[@name='methodToCall.performLookup.(!!org.kuali.rice.location.impl.state.StateBo!!).(((countryCode:document.newMaintainableObject.countryCode,code:document.newMaintainableObject.stateCode,))).((`document.newMaintainableObject.countryCode:countryCode,document.newMaintainableObject.stateCode:code,`)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;"
2408                 + getBaseUrlString() + "/kr/lookup.do;::::).anchor4']";
2409         waitAndClickByXpath(stateLookUp);
2410         waitAndTypeByName("code", "IN");
2411         waitAndClickSearch();
2412         waitAndClickReturnValue();
2413         String countyName = "Validation Test County" + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
2414         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.name']", countyName);
2415         waitAndClickByXpath("//input[@id='document.newMaintainableObject.active']");
2416         blanketApproveTest(docId);
2417     }
2418 
2419     protected void testLocationPostBlanketApprove() throws Exception {
2420         selectFrameIframePortlet();
2421         waitAndCreateNew();
2422         String docId = waitForDocId();
2423         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Validation Test Postal Code");
2424         assertBlanketApproveButtonsPresent();
2425         String countryLookUp = "//input[@name='methodToCall.performLookup.(!!org.kuali.rice.location.impl.country.CountryBo!!).(((code:document.newMaintainableObject.countryCode,))).((`document.newMaintainableObject.countryCode:code,`)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;"
2426                 + getBaseUrlString() + "/kr/lookup.do;::::).anchor4']";
2427         waitAndClickByXpath(countryLookUp);
2428         waitAndTypeByName("code", "US");
2429         waitAndClickSearch();
2430         waitAndClickReturnValue();
2431         String code = RandomStringUtils.randomNumeric(5);
2432         waitAndTypeByXpath(DOC_CODE_XPATH, code);
2433         String stateLookUp = "//input[@name='methodToCall.performLookup.(!!org.kuali.rice.location.impl.state.StateBo!!).(((countryCode:document.newMaintainableObject.countryCode,code:document.newMaintainableObject.stateCode,))).((`document.newMaintainableObject.countryCode:countryCode,document.newMaintainableObject.stateCode:code,`)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;"
2434                 + getBaseUrlString() + "/kr/lookup.do;::::).anchor4']";
2435         waitAndClickByXpath(stateLookUp);
2436         waitAndClickSearch();
2437         waitAndClickByXpath("//table[@id='row']/tbody/tr[4]/td[1]/a");
2438         String cityName = "Validation Test Postal Code " + code;
2439         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.cityName']", cityName);
2440         blanketApproveTest(docId);
2441     }
2442 
2443     protected void testLocationStateBlanketApprove() throws Exception {
2444         selectFrameIframePortlet();
2445         waitAndCreateNew();
2446         String docId = waitForDocId();
2447         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Validation Test State");
2448         assertBlanketApproveButtonsPresent();
2449 
2450         //jiraAwareWaitAndClick("methodToCall.performLookup.(!!org.kuali.rice.location.impl.country.CountryBo!!).(((code:document.newMaintainableObject.countryCode,))).((`document.newMaintainableObject.countryCode:code,`)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;" + getBaseUrlString() + "/kr/lookup.do;::::).anchor4");
2451         String countryLookUp = "//input[@name='methodToCall.performLookup.(!!org.kuali.rice.location.impl.country.CountryBo!!).(((code:document.newMaintainableObject.countryCode,))).((`document.newMaintainableObject.countryCode:code,`)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;"
2452                 + getBaseUrlString() + "/kr/lookup.do;::::).anchor4']";
2453         waitAndClickByXpath(countryLookUp);
2454         waitAndClickSearch();
2455         waitAndClickReturnValue();
2456         String code = RandomStringUtils.randomAlphabetic(2).toUpperCase();
2457         waitAndTypeByXpath(DOC_CODE_XPATH, code);
2458         String state = "Validation Test State " + code;
2459         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.name']", state);
2460         waitAndClickByXpath("//input[@id='document.newMaintainableObject.active']");
2461         blanketApproveTest(docId);
2462     }
2463 
2464     protected void testLookUp() throws Exception {
2465         waitForPageToLoad();
2466         selectFrameIframePortlet();
2467 
2468         // Mixed capitalization
2469         waitAndClick(By.xpath(SEARCH_XPATH_3));
2470         waitAndClickByLinkText(EDIT_LINK_TEXT, "edit button not present does user " + user + " have permission?");
2471         waitForTextPresent("ubmit");
2472         assertTextPresent("ave");
2473         assertTextPresent("pprove");
2474         assertTextPresent("lose");
2475         assertTextPresent("ancel");
2476     }
2477 
2478     protected void testReferenceCampusTypeBlanketApprove() throws Exception {
2479         selectFrameIframePortlet();
2480         String randomCode = searchForAvailableCode(1);
2481 
2482         waitAndCreateNew();
2483         String docId = waitForDocId();
2484         String dtsTwo = AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomCharsNot9Digits();
2485         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Validation Test Campus Type " + randomCode + " " + dtsTwo);
2486         waitAndTypeByXpath(DOC_CODE_XPATH, randomCode);
2487         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.name']", "Indianapolis"  + randomCode + dtsTwo);
2488 
2489         finishBlanketApprovalTest(docId);
2490     }
2491 
2492     protected void performParameterInquiry(String parameterField) throws Exception {
2493         waitAndTypeByName("name", parameterField);
2494         waitAndClickSearch();
2495         isElementPresentByLinkText(parameterField);
2496         waitAndClickByLinkText(parameterField);
2497         waitForPageToLoad();
2498         Thread.sleep(2000);
2499         switchToWindow("Kuali :: Inquiry");
2500         Thread.sleep(2000);
2501     }
2502 
2503     protected List<String> testLookUpParameterType(String docId, String parameterType, String parameterCode) throws Exception {
2504         performParameterInquiry(parameterType);
2505         assertEquals(parameterCode, getTextByXpath("//div[@class='tab-container']/table//span[@id='code.div']").trim().toLowerCase());
2506         assertEquals(parameterType, getTextByXpath("//div[@class='tab-container']/table//span[@id='name.div']").trim().toLowerCase());
2507         waitAndClickCloseWindow();
2508         switchToWindow("null");
2509         List<String> params = new ArrayList<String>();
2510         params.add(docId);
2511         params.add(parameterType);
2512         params.add(parameterCode);
2513 
2514         return params;
2515     }
2516 
2517     protected List<String> testLookUpParameter(String docId, String parameterName) throws Exception {
2518         performParameterInquiry(parameterName);
2519         assertEquals(parameterName, getTextByXpath(
2520                 "//div[@class='tab-container']/table//span[@id='name.div']").trim());
2521         assertEquals("Y", getTextByXpath("//div[@class='tab-container']/table//span[@id='value.div']")
2522                 .trim());
2523         waitAndClickCloseWindow();
2524         switchToWindow("null");
2525         List<String> params = new ArrayList<String>();
2526         params.add(docId);
2527         params.add(parameterName);
2528 
2529         return params;
2530     }
2531 
2532     protected void testPeopleFlowBlanketApprove() throws Exception {
2533         String docId = peopleFlowCreateNew();
2534 
2535         waitAndClickButtonByText("blanket approve");
2536         Thread.sleep(3000);
2537         checkForIncidentReport();
2538         jGrowl("Blanket Approve");
2539         Thread.sleep(5000);
2540 
2541         //Close the Doc
2542         //findElement(By.id("uif-close")).click();
2543         //Thread.sleep(3000);
2544         driver.switchTo().window(driver.getWindowHandles().toArray()[0].toString());
2545         findElement(By.cssSelector("img[alt=\"doc search\"]")).click();
2546         Thread.sleep(5000);
2547         jGrowl("Document Search is " + docId + " present?");
2548         selectFrameIframePortlet();
2549         findElement(By.cssSelector("td.infoline > input[name=\"methodToCall.search\"]")).click();
2550         Thread.sleep(5000);
2551         jGrowl("Is doc status final?");
2552         assertEquals(DOC_STATUS_FINAL, findElement(By.xpath("//table[@id='row']/tbody/tr/td[4]")).getText());
2553         driver.switchTo().defaultContent();
2554         findElement(By.name("imageField")).click();
2555         Thread.sleep(5000);
2556         // TODO open the document and verify data is as we expect.
2557     }
2558 
2559     protected void testPeopleFlowCreateNew() throws Exception {
2560         String docId = peopleFlowCreateNew();
2561 
2562         waitAndClickButtonByText("submit");
2563         Thread.sleep(3000);
2564         checkForDocError();
2565         checkForIncidentReport();
2566 
2567         //Close the Doc
2568         //findElement(By.id("uif-close")).click();
2569         //Thread.sleep(3000);
2570         driver.switchTo().window(driver.getWindowHandles().toArray()[0].toString());
2571         findElement(By.cssSelector("img[alt=\"doc search\"]")).click();
2572         Thread.sleep(5000);
2573         jGrowl("Document Search is " + docId + " present?");
2574         selectFrameIframePortlet();
2575         waitAndTypeByName("documentId", docId);
2576         findElement(By.cssSelector("td.infoline > input[name=\"methodToCall.search\"]")).click();
2577         Thread.sleep(5000);
2578         jGrowl("Is doc status final?");
2579         assertEquals(DOC_STATUS_FINAL, findElement(By.xpath("//table[@id='row']/tbody/tr/td[4]")).getText());
2580         driver.switchTo().defaultContent();
2581         findElement(By.name("imageField")).click();
2582         Thread.sleep(5000);
2583         // TODO open the document and verify data is as we expect.
2584     }
2585 
2586     private String peopleFlowCreateNew() throws InterruptedException {
2587         selectFrameIframePortlet();
2588 
2589         waitAndClickByLinkText("Create New");
2590 
2591         //Save docId
2592         waitForElementPresent("div[data-label='Document Number']");
2593         String docId = getText("div[data-label='Document Number']");
2594         assertTrue(docId != null);
2595         jGrowlSticky("Doc Id is " + docId);
2596 
2597         findElement(By.name("document.documentHeader.documentDescription")).clear();
2598         waitAndTypeByName("document.documentHeader.documentDescription", "Description for Document");
2599         waitAndSelectByName("document.newMaintainableObject.dataObject.namespaceCode", "KUALI - Kuali Systems");
2600         findElement(By.name("document.newMaintainableObject.dataObject.name")).clear();
2601         waitAndTypeByName("document.newMaintainableObject.dataObject.name", "Document Name" +
2602                 AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars());
2603 
2604         jGrowl("Add Member kr");
2605         findElement(By.name("newCollectionLines['document.newMaintainableObject.dataObject.members'].memberName")).clear();
2606         waitAndTypeByName("newCollectionLines['document.newMaintainableObject.dataObject.members'].memberName", "kr");
2607         waitAndClick(By.cssSelector("button[data-loadingmessage='Adding Line...']"));
2608         Thread.sleep(3000);
2609         checkForIncidentReport();
2610 
2611         jGrowl("Add Member admin");
2612         findElement(By.name("newCollectionLines['document.newMaintainableObject.dataObject.members'].memberName")).clear();
2613         waitAndTypeByName("newCollectionLines['document.newMaintainableObject.dataObject.members'].memberName", "admin");
2614         waitAndClick(By.cssSelector("button[data-loadingmessage='Adding Line...']"));
2615         Thread.sleep(3000);
2616         return docId;
2617     }
2618 
2619     protected void testTermLookupAssertions() throws Exception {
2620         testLookUp();
2621         assertTextPresent("Term Parameters");
2622         waitAndClick(By.xpath(CANCEL2_XPATH));
2623         passed();
2624     }
2625 
2626     protected void testTermSpecificationLookupAssertions() throws Exception {
2627         testLookUp();
2628         assertTextPresent("Context");
2629         waitAndClick(By.xpath(CANCEL2_XPATH));
2630         passed();
2631     }
2632 
2633     protected List<String> testVerifyModifiedParameter(String docId, String parameterName) throws Exception {
2634         performParameterInquiry(parameterName);
2635         assertEquals(parameterName, getTextByXpath("//div[@class='tab-container']/table//span[@id='name.div']").trim());
2636         assertEquals("N", getTextByXpath("//div[@class='tab-container']/table//span[@id='value.div']").trim());
2637         waitAndClickCloseWindow();
2638         switchToWindow("null");
2639         List<String> params = new ArrayList<String>();
2640         params.add(docId);
2641         params.add(parameterName);
2642 
2643         return params;
2644     }
2645 
2646     protected List<String> testVerifyCopyParameterType(String docId, String parameterType, String parameterCode) throws Exception
2647     {
2648         performParameterInquiry(parameterType);
2649         assertEquals(parameterType, getTextByXpath("//div[@class='tab-container']/table//span[@id='name.div']").trim().toLowerCase());
2650         waitAndClickCloseWindow();
2651         switchToWindow("null");
2652         List<String> params = new ArrayList<String>();
2653         params.add(docId);
2654         params.add(parameterType);
2655         params.add(parameterCode);
2656 
2657         return params;
2658     }
2659 
2660     protected List<String> testCreateNewPermission(String docId, String permissionName) throws Exception {
2661         waitForPageToLoad();
2662         Thread.sleep(2000);
2663         docId = waitForDocId();
2664         waitAndClickSave();
2665         waitForElementPresentByXpath("//div[contains(.,'Document Description (Description) is a required field.')]/img[@alt='error']");
2666         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Adding Permission removeme");
2667         waitAndClickSubmit();
2668         waitForElementPresentByXpath("//div[@class='error']");
2669         assertElementPresentByXpath("//div[contains(.,'Template (Template) is a required field.')]/img[@alt='error']");
2670         assertElementPresentByXpath("//div[contains(.,'Permission Namespace (Permission Namespace) is a required field.')]/img[@alt='error']");
2671         assertElementPresentByXpath("//div[contains(.,'Permission Name (Permission Name) is a required field.')]/img[@alt='error']");
2672         selectOptionByName("document.newMaintainableObject.templateId", "36");
2673         selectOptionByName("document.newMaintainableObject.namespaceCode", "KR-SYS");
2674         permissionName = "removeme" + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
2675         waitAndTypeByName("document.newMaintainableObject.name", permissionName);
2676         waitAndTypeByName("document.newMaintainableObject.description", "namespaceCode=KR*");
2677         checkByName("document.newMaintainableObject.active");
2678         waitAndClickSave();
2679         waitForElementPresentByXpath(SAVE_SUCCESSFUL_XPATH);
2680         assertEquals(DOC_STATUS_SAVED, getTextByXpath(DOC_STATUS_XPATH));
2681         waitAndClickSubmit();
2682         waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
2683         assertEquals(DOC_STATUS_ENROUTE, getTextByXpath(DOC_STATUS_XPATH));
2684         List<String> params = new ArrayList<String>();
2685         params.add(docId);
2686         params.add(permissionName);
2687 
2688         return params;
2689     }
2690 
2691     protected List<String> testLookUpPermission(String docId, String permissionName) throws Exception {
2692         waitAndTypeByName("name", permissionName);
2693         waitAndClickSearch();
2694         isElementPresentByLinkText(permissionName);
2695         List<String> params = new ArrayList<String>();
2696         params.add(docId);
2697         params.add(permissionName);
2698 
2699         return params;
2700     }
2701 
2702     protected List<String> testEditPermission(String docId, String permissionName) throws Exception {
2703         waitAndClickEdit();
2704         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Editing Permission removeme");
2705         uncheckByName("document.newMaintainableObject.active");
2706         waitAndClickSubmit();
2707         waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
2708         List<String> params = new ArrayList<String>();
2709         params.add(docId);
2710         params.add(permissionName);
2711 
2712         return params;
2713     }
2714 
2715     protected List<String> testVerifyPermission(String docId, String permissionName) throws Exception {
2716         waitAndTypeByName("name", permissionName);
2717         waitAndClickByXpath("//input[@title='Active Indicator - No']");
2718         waitAndClickSearch();
2719         isElementPresentByLinkText(permissionName);
2720         List<String> params = new ArrayList<String>();
2721         params.add(docId);
2722         params.add(permissionName);
2723 
2724         return params;
2725     }
2726 
2727     protected List<String> testCreateNewPerson(String docId, String personName) throws Exception  {
2728         waitForPageToLoad();
2729         docId = waitForDocId();
2730         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Adding Charlie Brown");
2731         waitAndTypeByName("document.documentHeader.explanation", "I want to add Charlie Brown to test KIM");
2732 
2733         //here You should also check for lower case validation for principalName, but it is skipped for now as there is an incident report error there.
2734         personName = "cbrown" + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
2735         waitAndTypeByName("document.principalName", personName);
2736         waitAndClickSave();
2737         waitForElementPresentByXpath(SAVE_SUCCESSFUL_XPATH);
2738         assertEquals(DOC_STATUS_SAVED, getTextByXpath(DOC_STATUS_XPATH));
2739         waitAndClickSubmit();
2740         waitForElementPresentByXpath("//div[contains(.,'At least one affiliation must be entered.')]/img[@alt='error']");
2741         assertElementPresentByXpath("//div[contains(.,'At least one name must be entered.')]/img[@alt='error']");
2742         selectOptionByName("newAffln.affiliationTypeCode", "STDNT");
2743         selectOptionByName("newAffln.campusCode", "BL");
2744         checkByName("newAffln.dflt");
2745         waitAndClickByName("methodToCall.addAffln.anchor");
2746         waitAndSelectByName("newName.nameCode", "PRM");
2747         selectOptionByName("newName.namePrefix", "Mr");
2748         waitAndTypeByName("newName.firstName", "Charlie");
2749         waitAndTypeByName("newName.lastName", "Brown");
2750         checkByName("newName.dflt");
2751         waitAndClickByName("methodToCall.addName.anchor");
2752         waitAndClickSubmit();
2753         waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
2754         assertEquals(DOC_STATUS_ENROUTE, getTextByXpath(DOC_STATUS_XPATH));
2755         List<String> params = new ArrayList<String>();
2756         params.add(docId);
2757         params.add(personName);
2758 
2759         return params;
2760     }
2761 
2762     protected List<String> testLookUpPerson(String docId, String personName) throws Exception {
2763         waitAndTypeByName("principalName", personName);
2764         waitAndClickSearch();
2765         isElementPresentByLinkText(personName);
2766         waitAndClickByName("methodToCall.clearValues");
2767         waitAndTypeByName("firstName", "Charlie");
2768         waitAndClickSearch();
2769         isElementPresentByLinkText(personName);
2770         waitAndClickByName("methodToCall.clearValues");
2771         waitAndTypeByName("lastName", "Brown");
2772         waitAndClickSearch();
2773         isElementPresentByLinkText(personName);
2774         waitAndClickByName("methodToCall.clearValues");
2775         waitAndTypeByName("campusCode", "BL");
2776         waitAndClickSearch();
2777         isElementPresentByLinkText(personName);
2778         List<String> params = new ArrayList<String>();
2779         params.add(docId);
2780         params.add(personName);
2781 
2782         return params;
2783     }
2784 
2785     protected List<String> testVerifyPerson(String docId, String personName) throws Exception {
2786         waitAndClickByLinkText(personName);
2787         waitForPageToLoad();
2788         Thread.sleep(5000);
2789         switchToWindow("Kuali :: Person");
2790         Thread.sleep(2000);
2791         assertEquals(personName, getTextByXpath("//div[@class='tab-container']/table//tr[2]/td[1]/div").trim());
2792         assertEquals("BL - BLOOMINGTON", getTextByXpath("//div[@class='tab-container']/table[3]//tr[2]/td[2]/div").trim());
2793         assertEquals("Student", getTextByXpath("//select/option[@selected]").trim());
2794         assertElementPresentByXpath("//table[@class='tab']//input[@title='close Overview']");
2795         assertElementPresentByXpath("//table[@class='tab']//input[@title='open Contact']");
2796         assertElementPresentByXpath("//table[@class='tab']//input[@title='open Privacy Preferences']");
2797         assertElementPresentByXpath("//table[@class='tab']//input[@title='open Membership']");
2798         waitAndClickByName("methodToCall.showAllTabs");
2799         waitForElementPresentByXpath("//table[@class='tab']//input[@title='close Overview']");
2800         assertElementPresentByXpath("//table[@class='tab']//input[@title='close Contact']");
2801         assertElementPresentByXpath("//table[@class='tab']//input[@title='close Privacy Preferences']");
2802         assertElementPresentByXpath("//table[@class='tab']//input[@title='close Membership']");
2803         waitAndClickByName("methodToCall.hideAllTabs");
2804         waitForElementPresentByXpath("//table[@class='tab']//input[@title='open Overview']");
2805         assertElementPresentByXpath("//table[@class='tab']//input[@title='open Contact']");
2806         assertElementPresentByXpath("//table[@class='tab']//input[@title='open Privacy Preferences']");
2807         assertElementPresentByXpath("//table[@class='tab']//input[@title='open Membership']");
2808         waitAndClickCloseWindow();
2809         switchToWindow("null");
2810         List<String> params = new ArrayList<String>();
2811         params.add(docId);
2812         params.add(personName);
2813 
2814         return params;
2815     }
2816 
2817     protected void testValidCharsConstraintIT() throws Exception {
2818         assertFocusTypeBlurValidation("field50", new String[]{"12.333", "-123.33"}, new String[]{"123.33"});
2819         assertFocusTypeBlurValidation("field51", new String[]{"A"}, new String[]{"-123.33"});
2820 
2821         // TODO continue to convert to assertFocusTypeBlurValidation
2822         assertFocusTypeBlurValidation("field77", new String[]{"1.1"},new String[]{"12"});
2823         assertFocusTypeBlurValidation("field52", new String[]{"5551112222"},new String[]{"555-111-1111"});
2824         assertFocusTypeBlurValidation("field53", new String[]{"1ClassName.java"},new String[]{"ClassName.java"});
2825         assertFocusTypeBlurValidation("field54", new String[]{"aaaaa"},new String[]{"aaaaa@kuali.org"});
2826         assertFocusTypeBlurValidation("field84", new String[]{"aaaaa"},new String[]{"http://www.kuali.org"});
2827         assertFocusTypeBlurValidation("field55", new String[]{"023512"},new String[]{"022812"});
2828         assertFocusTypeBlurValidation("field75", new String[]{"02/35/12"},new String[]{"02/28/12"});
2829         assertFocusTypeBlurValidation("field82", new String[]{"13:22"},new String[]{"02:33"});
2830         assertFocusTypeBlurValidation("field83", new String[]{"25:22"},new String[]{"14:33"});
2831         assertFocusTypeBlurValidation("field56", new String[]{"2020-06-02"},new String[]{"2020-06-02 03:30:30.22"});
2832         assertFocusTypeBlurValidation("field57", new String[]{"0"},new String[]{"2020"});
2833         assertFocusTypeBlurValidation("field58", new String[]{"13"},new String[]{"12"});
2834         assertFocusTypeBlurValidation("field61", new String[]{"5555-444"},new String[]{"55555-4444"});
2835         assertFocusTypeBlurValidation("field62", new String[]{"aa5bb6_a"},new String[]{"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"});
2836         assertFocusTypeBlurValidation("field63", new String[]{"#fff555"},new String[]{"aa22 _/"});
2837         assertFocusTypeBlurValidation("field64", new String[]{"AABB55"},new String[]{"ABCDEFGHIJKLMNOPQRSTUVWXY,Z abcdefghijklmnopqrstuvwxy,z"});
2838         assertFocusTypeBlurValidation("field76", new String[]{"AA~BB%"},new String[]{"abcABC %$#@&<>\\{}[]*-+!=.()/\"\"',:;?"});
2839         assertFocusTypeBlurValidation("field65", new String[]{"sdfs$#$# dsffs"},new String[]{"sdfs$#$#sffs"});
2840         assertFocusTypeBlurValidation("field66", new String[]{"abcABCD"},new String[]{"ABCabc"});
2841         assertFocusTypeBlurValidation("field67", new String[]{"(111)B-(222)A"},new String[]{"(12345)-(67890)"});
2842         assertFocusTypeBlurValidation("field68", new String[]{"A.66"},new String[]{"a.4"});
2843     }
2844 
2845     protected void assertFocusTypeBlurValidation(String field, String[] errorInputs, String[] validInputs) throws InterruptedException {
2846         assertFocusTypeBlurError(field, errorInputs);
2847         clearTextByName(field);
2848         assertFocusTypeBlurValid(field, validInputs);
2849     }
2850 
2851     protected void testSubCollectionSize() throws Exception {
2852         // click on collections page link
2853         waitAndClickByLinkText(COLLECTIONS_LINK_TEXT);
2854 
2855         // wait for collections page to load by checking the presence of a sub collection line item
2856         for (int second = 0;; second++) {
2857             if (second >= waitSeconds)
2858                 jiraAwareFail(TIMEOUT_MESSAGE
2859                         + " looking for "
2860                         + SUB_COLLECTION_UIF_DISCLOSURE_SPAN_UIF_HEADER_TEXT_SPAN_XPATH);
2861             try {
2862                 if (getText(SUB_COLLECTION_UIF_DISCLOSURE_SPAN_UIF_HEADER_TEXT_SPAN_XPATH).equals("SubCollection - (3 lines)"))
2863                 {
2864                     break;
2865                 }
2866             } catch (Exception e) {}
2867             Thread.sleep(1000);
2868         }
2869 
2870         // verify that sub collection sizes are displayed as expected
2871         assertEquals("SubCollection - (3 lines)", getText(SUB_COLLECTION_UIF_DISCLOSURE_SPAN_UIF_HEADER_TEXT_SPAN_XPATH));
2872         assertEquals("SubCollection - (2 lines)", getTextByXpath(
2873                 "//a[@id='subCollection1_line1_toggle']/span"));
2874     }
2875 
2876     protected void testConfigurationTestView(String idPrefix) throws Exception {
2877         waitForElementPresentByXpath("//label[@id='" + idPrefix + "TextInputField_label']");
2878 
2879         // testing for https://groups.google.com/a/kuali.org/group/rice.usergroup.krad/browse_thread/thread/1e501d07c1141aad#
2880         String styleValue = waitAndGetAttributeByXpath("//label[@id='" + idPrefix + "TextInputField_label']",
2881                 "style");
2882 
2883         // log.info("styleValue is " + styleValue);
2884         assertTrue(idPrefix + "textInputField label does not contain expected style", styleValue.replace(" ", "").contains("color:red"));
2885 
2886         // get current list of options
2887         String refreshTextSelectLocator = "//select[@id='" + idPrefix + "RefreshTextField_control']";
2888         String[] options1 = getSelectOptionsByXpath(refreshTextSelectLocator);
2889         String dropDownSelectLocator = "//select[@id='" + idPrefix + "DropDown_control']";
2890         selectByXpath(dropDownSelectLocator, "Vegetables");
2891         Thread.sleep(3000);
2892 
2893         //get list of options after change
2894         String[] options2 = getSelectOptionsByXpath(refreshTextSelectLocator);
2895 
2896         //verify that the change has occurred
2897         assertFalse("Field 1 selection did not change Field 2 options https://jira.kuali.org/browse/KULRICE-8163 Configuration Test View Conditional Options doesn't change Field 2 options based on Field 1 selection",
2898                 options1[options1.length - 1].equalsIgnoreCase(options2[options2.length - 1]));
2899 
2900         //confirm that control gets disabled
2901         selectByXpath(dropDownSelectLocator, "None");
2902         Thread.sleep(3000);
2903         assertEquals("true", waitAndGetAttributeByXpath(refreshTextSelectLocator, "disabled"));
2904     }
2905 
2906     //    protected void testTravelAccountTypeLookup() throws Exception {
2907     //        selectFrameIframePortlet();
2908     //
2909     //        //Blank Search
2910     //        waitAndClickByXpath("//*[contains(button,\"earch\")]/button[1]");
2911     //        Thread.sleep(4000);
2912     //        assertElementPresentByXpath("//table[@class='uif-tableCollectionLayout dataTable']//tr[contains(td[1],'CAT')]");
2913     //        assertElementPresentByXpath("//table[@class='uif-tableCollectionLayout dataTable']//tr[contains(td[1],'EAT')]");
2914     //        assertElementPresentByXpath("//table[@class='uif-tableCollectionLayout dataTable']//tr[contains(td[1],'IAT')]");
2915     //
2916     //        //search with each field
2917     //        waitAndTypeByName("lookupCriteria[accountTypeCode]", "CAT");
2918     //        waitAndClickByXpath("//*[contains(button,\"earch\")]/button[1]");
2919     //        Thread.sleep(2000);
2920     //        assertElementPresentByXpath("//table[@class='uif-tableCollectionLayout dataTable']//tr[contains(td[1],'CAT')]");
2921     //        waitAndClickByXpath("//*[contains(button,\"earch\")]/button[2]");
2922     //        Thread.sleep(2000);
2923     //        waitAndTypeByName("lookupCriteria[name]", "Expense Account Type");
2924     //        waitAndClickByXpath("//*[contains(button,\"earch\")]/button[1]");
2925     //        Thread.sleep(4000);
2926     //        assertElementPresentByXpath("//table[@class='uif-tableCollectionLayout dataTable']//tr[contains(td[1],'EAT')]");
2927     //
2928     //        //Currently No links available for Travel Account Type Inquiry so cant verify heading and values.
2929     //    }
2930 
2931     protected void testCategoryLookUp() throws Exception {
2932         waitForPageToLoad();
2933         selectFrameIframePortlet();
2934         waitAndClickByXpath("//button[contains(.,'earch')]");
2935         Thread.sleep(3000);
2936         waitForPageToLoad();
2937         findElement(By.tagName("body")).getText().contains("Actions"); // there are no actions, but the header is the only unique text from searching
2938 
2939         // Category's don't have actions (yet)
2940         //waitAndClick("id=u80");
2941         //waitForPageToLoad();
2942         //waitAndClick("id=u86");
2943         //waitForPageToLoad();
2944         //selectWindow("null");
2945         //waitAndClick("xpath=(//input[@name='imageField'])[2]");
2946         //waitForPageToLoad();
2947         //passed();
2948     }
2949 
2950     protected void testCreateSampleEDocLite() throws Exception {
2951         waitForPageToLoad();
2952         Thread.sleep(3000);
2953         assertEquals("Kuali Portal Index", getTitle());
2954         selectFrameIframePortlet();
2955         waitAndClickByXpath("//input[@name='methodToCall.search' and @alt='search']");
2956         waitForPageToLoad();
2957 
2958         // click on the create new.
2959         waitAndClickByLinkText("Create Document");
2960         waitForPageToLoad();
2961         Thread.sleep(3000);
2962         String docId = getTextByXpath("//table/tbody/tr[4]/td[@class='datacell1']");
2963         waitAndTypeByName("userName", "Viral Chauhan");
2964         waitAndTypeByName("rqstDate", "12/03/2020");
2965         checkByName("fundedBy");
2966         waitAndTypeByName("addText", "Note Added.");
2967         waitAndClickByXpath("//td[@class='datacell']/div/img");
2968         waitAndClickByXpath("//input[@value='submit']");
2969         assertEquals(Boolean.FALSE,(Boolean) isElementPresentByXpath("//input[@value='submit']"));
2970         assertEquals(Boolean.FALSE, (Boolean) isElementPresentByXpath("//input[@value='save']"));
2971         assertEquals(Boolean.FALSE, (Boolean) isElementPresentByXpath("//input[@value='cancel']"));
2972         waitForPageToLoad();
2973         selectTopFrame();
2974         waitAndClickDocSearch();
2975         waitForPageToLoad();
2976         selectFrameIframePortlet();
2977         waitAndClickByXpath("//input[@name='methodToCall.search' and @alt='search']");
2978         waitForElementPresent(By.linkText(docId));
2979     }
2980 
2981     protected void testTermLookUp() throws Exception {
2982         testLookUp();
2983         assertTextPresent("Term Parameters");
2984         waitAndClick(By.xpath(CANCEL2_XPATH));
2985         passed();
2986     }
2987 
2988     protected void testWorkFlowRouteRulesBlanketApp() throws Exception {
2989         String random = AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomCharsNot9Digits();
2990         waitForPageToLoad();
2991         Thread.sleep(3000);
2992         assertEquals("Kuali Portal Index", getTitle());
2993         selectFrameIframePortlet();
2994 
2995         // click on the create new button
2996         waitAndClickCreateNew();
2997 
2998         // lookup on the Document Type Name
2999         waitAndClickByName("methodToCall.performLookup.(!!org.kuali.rice.kew.doctype.bo.DocumentType!!).(((name:documentTypeName))).((``)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;;::::).anchor");
3000 
3001         // type in the name field the text RoutingRuleDocument
3002         waitAndTypeByName("name", "RoutingRuleDocument");
3003 
3004         // click the search button
3005         waitAndClickSearch();
3006 
3007         // click the return value link
3008         waitAndClickReturnValue();
3009 
3010         // lookup on the Rule Template Name
3011         waitAndClickByName("methodToCall.performLookup.(!!org.kuali.rice.kew.rule.bo.RuleTemplateBo!!).(((name:ruleTemplateName))).((``)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;;::::).anchor");
3012 
3013         // type in the name field the text RuleRoutingTemplate
3014         waitAndTypeByName("name", "RuleRoutingTemplate");
3015 
3016         // click the search button
3017         waitAndClickSearch();
3018 
3019         // click the return value link
3020         waitAndClickReturnValue("testWorkFlowRouteRulesBlanketApp");
3021 
3022         // click the create new button
3023         waitAndClickByName("methodToCall.createRule");
3024         waitForPageToLoad();
3025         String docId = waitForDocId();
3026         assertTrue(isElementPresentByName(CANCEL_NAME));
3027 
3028         // type in the Document Overview Description the text Test Routing Rule
3029         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Test Routing Rule " + random);
3030 
3031         // click the Force Action checkbox
3032         waitAndClickByXpath("//input[@id='document.newMaintainableObject.forceAction']");
3033 
3034         // type in the Description text area the text Test Routing Rule1
3035         waitAndTypeByXpath("//textarea[@id='document.newMaintainableObject.description']", "Test Routing Rule1 "
3036                 + random);
3037 
3038         // type in the Document type name field the text DocumentTypeDocument
3039         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.fieldValues(1321~docTypeFullName)']",
3040                 "DocumentTypeDocument");
3041 
3042         // lookup on Person
3043         waitAndClickByName("methodToCall.performLookup.(!!org.kuali.rice.kim.impl.identity.PersonImpl!!).(((principalName:document.newMaintainableObject.add.personResponsibilities.principalName,))).((`document.newMaintainableObject.add.personResponsibilities.principalName:principalName,`)).((<>)).(([])).((**)).((^^)).((&&)).((/personImpl/)).((~~)).(::::;"
3044                 + getBaseUrlString() + "/kr/lookup.do;::::).anchor15");
3045 
3046         // click the search button
3047         waitAndClickSearch();
3048 
3049         // click the return value
3050         waitAndClickReturnValue();
3051 
3052         // select from the Action Request ACKNOWLEDGE
3053         selectByXpath("//select[@id='document.newMaintainableObject.add.personResponsibilities.actionRequestedCd']",
3054                 "ACKNOWLEDGE");
3055 
3056         // type in the Priority field the text 1
3057         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.add.personResponsibilities.priority']", "1");
3058 
3059         // click the add button
3060         waitAndClickByName("methodToCall.addLine.personResponsibilities.(!!org.kuali.rice.kew.rule.PersonRuleResponsibility!!).(:::;15;:::).anchor15");
3061         waitForPageToLoad();
3062 
3063         // click Blanket Approve
3064         waitAndClickByName(BLANKET_APPROVE_NAME);
3065 
3066         // doc search for the docId
3067         waitForPageToLoad();
3068         driver.switchTo().defaultContent(); //selectWindow("null");
3069         waitAndClickDocSearch();
3070         waitForPageToLoad();
3071         assertEquals("Kuali Portal Index", getTitle());
3072         selectFrameIframePortlet();
3073         waitAndTypeByName("documentId", docId);
3074         waitAndClickSearch();
3075 
3076         // Expect the doc status to be FINAL
3077         waitForElementPresent(By.linkText(docId));
3078         if (isElementPresent(By.linkText(docId))) {
3079             if (!DOC_STATUS_FINAL.equalsIgnoreCase(getTextByXpath(DOC_STATUS_XPATH_2))) {
3080                 jiraAwareFail("WorkFlowRouteRulesBlanketApp expected:<[FINAL]> but was " + getTextByXpath(DOC_STATUS_XPATH_2));
3081             }
3082         } else {
3083             assertEquals(docId, getTextByXpath(DOC_ID_XPATH_2));
3084             assertEquals(DOC_STATUS_FINAL, getTextByXpath(DOC_STATUS_XPATH_2));
3085         }
3086     }
3087 
3088     protected void testCreateNewRRDTravelRequestDestRouting() throws Exception {
3089         selectFrameIframePortlet();
3090 
3091         // Create new Routing Rules Delegation
3092         waitAndClick("img[alt=\"create new\"]");
3093 
3094         // Lookup parent rule, click lookup icon
3095         waitAndClickByName(
3096                 "methodToCall.performLookup.(!!org.kuali.rice.kew.rule.RuleBaseValues!!).(((id:parentRuleId))).((``)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;;::::).anchor");
3097 
3098         // Search
3099         waitAndClickByXpath("//td[@class='infoline']/input[@name='methodToCall.search']");
3100 
3101         // return value for 1046 TravelRequest.Destination.LasVegas TravelRequest-DestinationRouting
3102         waitAndClick("a[title=\"return valueRule Id=1046 \"]");
3103 
3104         // Select the parent rule we just returned
3105         waitAndClickByName("parentResponsibilityId");
3106 
3107         // Click continue
3108         waitAndClickByName("methodToCall.createDelegateRule");
3109 
3110         waitAndClickCancel();
3111         waitAndClickByName("methodToCall.processAnswer.button0");
3112         waitForPageToLoad();
3113         driver.switchTo().defaultContent();
3114         waitAndClickByXpath("(//input[@name='imageField'])[2]");
3115         passed();
3116     }
3117 
3118     protected void testWorkFlowRouteRulesCreateNew() throws Exception {
3119         waitForPageToLoad();
3120         Thread.sleep(5000);
3121         assertEquals("Kuali Portal Index", getTitle());
3122         selectFrameIframePortlet();
3123         waitAndClickCreateNew();
3124         waitAndClickByName(CANCEL_NAME, "https://jira.kuali.org/browse/KULRICE-8161 Work Flow Route Rules cancel new yields 404 not found");
3125 
3126         // KULRICE-7753 : WorkFlowRouteRulesIT cancel confirmation missing from create new Route Rules.
3127         waitAndClickByName("methodToCall.processAnswer.button0");
3128         passed();
3129     }
3130 
3131     /**
3132      * tests that a Routing Rule maintenance document is created for an edit operation originating
3133      * from a lookup screen
3134      */
3135     protected void testWorkFlowRouteRulesEditRouteRules() throws Exception {
3136         waitForPageToLoad();
3137         assertEquals("Kuali Portal Index", getTitle());
3138         selectFrameIframePortlet();
3139         waitAndClickSearch();
3140         waitAndClickEdit();
3141         waitForPageToLoad();
3142         selectFrameIframePortlet();
3143         waitAndClickCancel();
3144         waitAndClickByName("methodToCall.processAnswer.button0");
3145         passed();
3146     }
3147 
3148     protected void createNewEnterDetails() throws InterruptedException {
3149         // overload to utilize
3150         fail("createNewEnterDetails must be implemented by test class");
3151     }
3152 
3153 //    protected String createNewTemplateMethod() throws InterruptedException {
3154 //        waitAndCreateNew();
3155 //        String docId = waitForDocId();
3156 //
3157 //        createNewEnterDetails();
3158 //
3159 //        // Ad Hoc Recipients with current user to test Action List
3160 //        addAdHocRecipientsPerson(new String[]{getUserName(), "F"}); // FYI
3161 //
3162 //        waitAndClickSave();
3163 //        waitAndClickSubmit();
3164 //        waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, CREATE_NEW_DOCUMENT_NOT_SUBMITTED_SUCCESSFULLY_MESSAGE_TEXT);
3165 //
3166 //        // Action List
3167 //        assertActionList(docId, "F", "ENROUTE"); // FYI
3168 //
3169 //        assertDocSearch(docId, DOC_STATUS_FINAL);
3170 //        selectTopFrame();
3171 //        return docId;
3172 //    }
3173 //
3174 //    protected String createNewTemplateMethodNoAction() throws InterruptedException {
3175 //        waitAndCreateNew();
3176 //        String docId = waitForDocId();
3177 //
3178 //        createNewEnterDetails();
3179 //
3180 //        waitAndClickSave();
3181 //        waitAndClickSubmit();
3182 //        waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, CREATE_NEW_DOCUMENT_NOT_SUBMITTED_SUCCESSFULLY_MESSAGE_TEXT);
3183 //
3184 //        assertDocSearch(docId, DOC_STATUS_FINAL);
3185 //        selectTopFrame();
3186 //        return docId;
3187 //    }
3188 
3189     protected void waitAndClickActionList() throws InterruptedException {
3190         WebDriverUtils.jGrowl(driver, "Click Action List", false, "Click Action List");
3191         selectTopFrame();
3192         waitAndClickByXpath("//img[@alt='action list']");
3193     }
3194 
3195     protected void testLookUpComponent(String docId, String componentName, String componentCode) throws Exception {
3196         selectFrameIframePortlet();
3197         //Lookup
3198         waitAndTypeByName("name", componentName);
3199         waitAndClickSearch();
3200         isElementPresentByLinkText(componentName);
3201         waitAndClickByLinkText(componentName);
3202         waitForPageToLoad();
3203         Thread.sleep(2000);
3204         switchToWindow("Kuali :: Inquiry");
3205         Thread.sleep(2000);
3206         assertEquals(componentName, getTextByXpath("//div[@class='tab-container']/table//span[@id='name.div']").trim());
3207         assertEquals(componentCode, getTextByXpath("//div[@class='tab-container']/table//span[@id='code.div']").trim());
3208         waitAndClickCloseWindow();
3209         switchToWindow("null");
3210     }
3211 
3212     protected void testEditComponent(String docId, String componentName, String componentCode) throws Exception {
3213         selectFrameIframePortlet();
3214         waitAndClickEdit();
3215         waitForPageToLoad();
3216         docId = waitForDocId();
3217         waitAndTypeByName("document.documentHeader.documentDescription", "Editing Test Component");
3218         clearTextByName("document.newMaintainableObject.name");
3219         waitAndTypeByName("document.newMaintainableObject.name", componentName);
3220         waitAndClickSave();
3221         waitAndClickSubmit();
3222         waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
3223         assertDocSearch(docId, DOC_STATUS_FINAL);
3224         selectTopFrame();
3225     }
3226 
3227     protected void testCopyComponent(String docId, String componentName, String componentCode) throws Exception {
3228         selectFrameIframePortlet();
3229         waitAndClickCopy();
3230         waitForPageToLoad();
3231         docId = waitForDocId();
3232         waitAndTypeByName("document.documentHeader.documentDescription", "Copying Test Component");
3233         selectOptionByName("document.newMaintainableObject.namespaceCode", "KR-IDM");
3234         waitAndTypeByName("document.newMaintainableObject.code", componentCode);
3235         clearTextByName("document.newMaintainableObject.name");
3236         waitAndTypeByName("document.newMaintainableObject.name", componentName);
3237         waitAndClickSave();
3238         waitAndClickSubmit();
3239         waitForPageToLoad();
3240         checkForDocError();
3241         waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
3242         assertDocSearch(docId, DOC_STATUS_FINAL);
3243         selectTopFrame();
3244     }
3245 
3246     protected void testVerifyCopyComponent(String docId, String componentName, String componentCode) throws Exception {
3247         selectFrameIframePortlet();
3248         waitAndTypeByName("name", componentName);
3249         waitAndClickSearch();
3250         isElementPresentByLinkText(componentName);
3251         waitAndClickByLinkText(componentName);
3252         waitForPageToLoad();
3253         Thread.sleep(2000);
3254         switchToWindow("Kuali :: Inquiry");
3255         Thread.sleep(2000);
3256         assertEquals(componentName, getTextByXpath("//div[@class='tab-container']/table//span[@id='name.div']").trim());
3257         assertEquals(componentCode, getTextByXpath("//div[@class='tab-container']/table//span[@id='code.div']").trim());
3258         waitAndClickCloseWindow();
3259         switchToWindow("null");
3260     }
3261 
3262     /**
3263      * Test the tooltip and external help on the page
3264      */
3265     protected void testPageHelp() throws Exception {
3266         // test tooltip help
3267         fireMouseOverEventByXpath("//h2/span[@class='uif-headerText-span']");
3268         assertEquals("Sample text for page help", getText("td.jquerybubblepopup-innerHtml"));
3269 
3270         // test external help
3271         waitAndClickByXpath("//input[@alt='Help for Help Page']");
3272         Thread.sleep(5000);
3273         switchToWindow("Kuali Foundation");
3274         Thread.sleep(5000);
3275         switchToWindow(CONFIGURATION_VIEW_WINDOW_TITLE);
3276     }
3277 
3278     /**
3279      * Test the tooltip help on the section and fields
3280      */
3281     protected void testTooltipHelp() throws Exception {
3282         // verify that no tooltips are displayed initially
3283         if (isElementPresentByXpath("//td[contains(text(),'Sample text for section help - tooltip help')]")) {
3284             assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for section help - tooltip help')]"));
3285         }
3286 
3287         if (isElementPresentByXpath("//td[contains(text(),'Sample text for field help - label left')]")) {
3288             assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for field help - label left')]"));
3289         }
3290 
3291         if (isElementPresentByXpath("//td[contains(text(),'Sample text for field help - label right')]")) {
3292             assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for field help - label right')]"));
3293         }
3294 
3295         if (isElementPresentByXpath("//td[contains(text(),'Sample text for field help - label top')]")) {
3296             assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for field help - label top')]"));
3297         }
3298 
3299         if (isElementPresentByXpath("//td[contains(text(),'Sample text for standalone help widget tooltip which will never be rendered')]")) {
3300             assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for standalone help widget tooltip which will never be rendered')]"));
3301         }
3302 
3303         if (isElementPresentByXpath("//td[contains(text(),'Sample text for field help - there is also a tooltip on the label but it is overridden by the help tooltip')]")) {
3304             assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for field help - there is also a tooltip on the label but it is overridden by the help tooltip')]"));
3305         }
3306 
3307         if (isElementPresentByXpath("//td[contains(text(),'Sample text for label tooltip - this will not be rendered as it is overridden by the help tooltip')]")) {
3308             assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for label tooltip - this will not be rendered as it is overridden by the help tooltip')]"));
3309         }
3310 
3311         if (isElementPresentByXpath("//td[contains(text(),'Sample text for field help - there is also an on-focus tooltip')]")) {
3312             assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for field help - there is also an on-focus tooltip')]"));
3313         }
3314 
3315         if (isElementPresentByXpath("//td[contains(text(),'Sample text for on-focus event tooltip')]")) {
3316             assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for on-focus event tooltip')]"));
3317         }
3318 
3319         if (isElementPresentByXpath("//td[contains(text(),'Sample text for check box help')]")) {
3320             assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for check box help')]"));
3321         }
3322 
3323         // test tooltip help of section header
3324         fireMouseOverEventByXpath("//div[@id='ConfigurationTestView-Help-Section1']/div/h3[@class='uif-headerText']");
3325         assertTrue(isVisibleByXpath("//td[contains(text(),'Sample text for section help - tooltip help')]"));
3326         String javascript="var element = document.getElementsByClassName('jquerybubblepopup jquerybubblepopup-black');" + "element[0].style.display='none'";
3327         ((JavascriptExecutor) driver).executeScript(javascript);
3328         Thread.sleep(3000);
3329         assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for section help - tooltip help')]"));
3330 
3331         // verify that no external help exist
3332         assertFalse(isElementPresent("#ConfigurationTestView-Help-Section1 input.uif-helpImage"));
3333 
3334         // test tooltip help of field with label to the left
3335         fireMouseOverEventByXpath("//label[@id='field-label-left_label']");
3336         Thread.sleep(3000);
3337         assertTrue(isVisibleByXpath("//td[contains(text(),'Sample text for field help - label left')]"));
3338         javascript="var element = document.getElementsByClassName('jquerybubblepopup jquerybubblepopup-black');" +
3339                 "element[1].style.display='none'";
3340         Thread.sleep(3000);
3341         ((JavascriptExecutor) driver).executeScript(javascript);
3342         assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for field help - label left')]"));
3343 
3344         // test tooltip help of field with label to the right
3345         fireMouseOverEventByXpath("//label[@id='field-label-right_label']");
3346         Thread.sleep(3000);
3347         assertTrue(isVisibleByXpath("//td[contains(text(),'Sample text for field help - label righ')]"));
3348         javascript="var element = document.getElementsByClassName('jquerybubblepopup jquerybubblepopup-black');" +"element[2].style.display='none'";
3349         ((JavascriptExecutor) driver).executeScript(javascript);
3350         Thread.sleep(3000);
3351         assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for field help - label righ')]"));
3352 
3353         // test tooltip help of field with label to the top
3354         fireMouseOverEventByXpath("//label[@id='field-label-top_label']");
3355         Thread.sleep(3000);
3356         assertTrue(isVisibleByXpath("//td[contains(text(),'Sample text for field help - label top')]"));
3357         javascript="var element = document.getElementsByClassName('jquerybubblepopup jquerybubblepopup-black');" + "element[3].style.display='none'";
3358         ((JavascriptExecutor) driver).executeScript(javascript);
3359         Thread.sleep(3000);
3360         assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for field help - label top')]"));
3361 
3362         // verify that standalone help with tooltip is not rendered
3363         assertFalse(isElementPresentByXpath("//*[@id='standalone-help-not-rendered']"));
3364 
3365         // test tooltip help when it overrides a tooltip
3366         fireMouseOverEventByXpath("//label[@id='override-tooltip_label']");
3367         Thread.sleep(3000);
3368         assertTrue(isVisibleByXpath("//td[contains(text(),'Sample text for field help - there is also a tooltip on the label but it is overridden by the help tooltip')]"));
3369         if (isElementPresentByXpath("//td[contains(text(),'Sample text for label tooltip - this will not be rendered as it is overridden by the help tooltip')]")) {
3370             assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for label tooltip - this will not be rendered as it is overridden by the help tooltip')]"));
3371         }
3372         javascript="var element = document.getElementsByClassName('jquerybubblepopup jquerybubblepopup-black');" + "element[4].style.display='none'";
3373         ((JavascriptExecutor) driver).executeScript(javascript);
3374         Thread.sleep(3000);
3375         assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for field help - there is also a tooltip on the label but it is overridden by the help tooltip')]"));
3376 
3377         // test tooltip help in conjunction with a focus event tooltip
3378         fireMouseOverEventByXpath("//input[@id='on-focus-tooltip_control']");
3379         assertTrue(isVisibleByXpath("//td[contains(text(),'Sample text for on-focus event tooltip')]"));
3380         fireMouseOverEventByXpath("//label[@id='on-focus-tooltip_label']");
3381         assertTrue(isVisibleByXpath("//td[contains(text(),'Sample text for field help - there is also an on-focus tooltip')]"));
3382         javascript="var element = document.getElementsByClassName('jquerybubblepopup jquerybubblepopup-black');" +"element[5].style.display='none'";
3383         ((JavascriptExecutor) driver).executeScript(javascript);
3384         Thread.sleep(3000);
3385         javascript="var element = document.getElementsByClassName('jquerybubblepopup jquerybubblepopup-black');" + "element[6].style.display='none'";
3386         ((JavascriptExecutor) driver).executeScript(javascript);
3387         Thread.sleep(3000);
3388         assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for field help - there is also an on-focus tooltip')]"));
3389         assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for on-focus event tooltip')]"));
3390 
3391         // test tooltip help against a check box - help contains html
3392         fireMouseOverEventByXpath("//label[@id='checkbox_label']");
3393         assertTrue(isVisibleByXpath("//td[contains(text(),'Sample text for check box help')]"));
3394         javascript="var element = document.getElementsByClassName('jquerybubblepopup jquerybubblepopup-black');" + "element[7].style.display='none'";
3395         ((JavascriptExecutor) driver).executeScript(javascript);
3396         Thread.sleep(3000);
3397         assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for check box help')]"));
3398     }
3399 
3400     /**
3401      * Test the tooltip help on the sub-section and fields that are display only
3402      */
3403     protected void testDisplayOnlyTooltipHelp() throws Exception {
3404         // verify that no tooltips are displayed initially
3405         if (isElementPresentByXpath("//td[contains(text(),'Sample text for sub-section help')]")) {
3406             assertFalse(isVisible("//td[contains(text(),'Sample text for sub-section help')]"));
3407         }
3408 
3409         if (isElementPresentByXpath("//td[contains(text(),'Sample text for read only field help')]")) {
3410             assertFalse(isVisible("//td[contains(text(),'Sample text for read only field help')]"));
3411         }
3412 
3413         // test tooltip help of sub-section header
3414         fireMouseOverEventByXpath("//span[contains(text(),'Display only fields')]");
3415         assertTrue(isVisibleByXpath("//td[contains(text(),'Sample text for sub-section help')]"));
3416         String javascript="var element = document.getElementsByClassName('jquerybubblepopup jquerybubblepopup-black');" +
3417                 "element[0].style.display='none'";
3418         ((JavascriptExecutor) driver).executeScript(javascript);
3419         assertFalse(isVisibleByXpath("//td[contains(text(),'Sample text for sub-section help')]"));
3420 
3421         // test tooltip help of display only data field
3422         fireMouseOverEventByXpath("//label[@for='display-field_control']");
3423         assertTrue(isVisibleByXpath("//td[contains(text(),'Sample text for read only field help')]"));
3424         javascript="var element = document.getElementsByClassName('jquerybubblepopup jquerybubblepopup-black');" +
3425                 "element[0].style.display='none'";
3426         ((JavascriptExecutor) driver).executeScript(javascript);
3427     }
3428 
3429     /**
3430      * Test the tooltip help on the section and fields with no content
3431      */
3432     protected void testMissingTooltipHelp() throws Exception {
3433         // verify that no tooltips are displayed initially
3434         assertFalse(isElementPresentByXpath("//*[@class='jquerybubblepopup jquerybubblepopup-black']"));
3435 
3436         // verify that no external help exist
3437         assertFalse(isElementPresent("#ConfigurationTestView-Help-Section2 input.uif-helpImage"));
3438 
3439         // test tooltip help of section header
3440         fireMouseOverEventByXpath("//div[@id='ConfigurationTestView-Help-Section2']/div");
3441         assertFalse(isElementPresentByXpath("//*[@class='jquerybubblepopup jquerybubblepopup-black']"));
3442         assertFalse(isElementPresentByXpath("//*[@class='jquerybubblepopup jquerybubblepopup-black']"));
3443 
3444         // test tooltip help of field
3445         fireMouseOverEventByXpath("//label[@id='missing-tooltip-help_label']");
3446         assertFalse(isElementPresentByXpath("//*[@class='jquerybubblepopup jquerybubblepopup-black']"));
3447         assertFalse(isElementPresentByXpath("//*[@class='jquerybubblepopup jquerybubblepopup-black']"));
3448     }
3449 
3450     protected void testMultiValueSelectAllPages() throws InterruptedException {
3451         waitAndClickButtonByText(SEARCH);
3452         acceptAlertIfPresent();
3453         assertButtonDisabledByText(RETURN_SELECTED_BUTTON_TEXT);
3454 
3455         // select all, all checkboxes should be checked and return button enabled
3456         waitAndClickDropDown("select all items");
3457         acceptAlertIfPresent();
3458         if (!areAllMultiValueSelectsChecked()) {
3459             JiraAwareFailureUtils.fail("select all items failure", this);
3460         }
3461         assertButtonEnabledByText(RETURN_SELECTED_BUTTON_TEXT);
3462 
3463         boolean anotherPageOfResults = false;
3464         if (Integer.parseInt(multiValueResultCount()) > 10) {
3465             anotherPageOfResults = true;
3466         }
3467 
3468         // all should be checked and button enabled on the next page as well (server side paging)
3469         if (!anotherPageOfResults) {
3470             JiraAwareFailureUtils.fail("select all items server side paging failure not enough results for next page",
3471                     this);
3472         }
3473         waitAndClickByLinkText("Next");
3474 
3475         if (!areAllMultiValueSelectsChecked()) {
3476             JiraAwareFailureUtils.fail("select all items server side paging failure", this);
3477         }
3478         assertButtonEnabledByText(RETURN_SELECTED_BUTTON_TEXT);
3479 
3480         // deselect all no checkboxes should be checked and return button disabled
3481         waitAndClickDropDown("deselect all items");
3482         if (!areNoMultiValueSelectsChecked()) {
3483             JiraAwareFailureUtils.fail("deselect all items failure", this);
3484         }
3485         assertButtonDisabledByText(RETURN_SELECTED_BUTTON_TEXT);
3486 
3487         waitAndClickByLinkText("Previous");
3488         if (!areNoMultiValueSelectsChecked()) {
3489             JiraAwareFailureUtils.fail("deselect all items failure", this);
3490         }
3491         assertButtonDisabledByText(RETURN_SELECTED_BUTTON_TEXT);
3492     }
3493 
3494     protected void acceptAlertIfPresent() {
3495         WebDriverUtils.acceptAlertIfPresent(driver);
3496     }
3497 
3498     protected void testMultiValueSelectAllThisPage() throws InterruptedException {
3499         waitAndClickButtonByText(SEARCH);
3500         acceptAlertIfPresent();
3501         assertButtonDisabledByText(RETURN_SELECTED_BUTTON_TEXT);
3502 
3503         // select all on this page, all checkboxes should be checked and return button enabled
3504         assertMultiValueSelectAllThisPage();
3505 
3506         boolean anotherPageOfResults = false;
3507         if (Integer.parseInt(multiValueResultCount()) > 5) {
3508             anotherPageOfResults = true;
3509         }
3510 
3511         // the next page should not have any checkboxes checked return button should still be enabled
3512         waitAndClickByLinkText("Next");
3513         if (!areNoMultiValueSelectsChecked()) {
3514             if (anotherPageOfResults) {
3515                 JiraAwareFailureUtils.fail("select all items on this page failure", this);
3516             } else {
3517                 JiraAwareFailureUtils.fail("select all items on this page failure not enough results for next page",
3518                         this);
3519             }
3520         }
3521         assertButtonEnabledByText(RETURN_SELECTED_BUTTON_TEXT);
3522 
3523         // back to the previous page, checkboxes should be checked and return button enabled still
3524         waitAndClickByLinkText("Previous");
3525         if (!areAllMultiValueSelectsChecked()) {
3526             JiraAwareFailureUtils.fail("select all items on previous page failure", this);
3527         }
3528 
3529         // deselect no checkboxes should be checked and the return button should be disabled
3530         assertMultiValueDeselectAllThisPage();
3531     }
3532 
3533     /**
3534      * Test the external help on the section and fields
3535      */
3536     protected void testExternalHelp2() throws Exception {
3537         // test external help of section
3538         assertPopUpWindowUrl(By.cssSelector("input[title=\"Help for External Help\"]"), "HelpWindow", "http://www.kuali.org/?section");
3539 
3540         // test external help of field with label left
3541         assertPopUpWindowUrl(By.xpath("//div[@id='field-label-left-external-help']/fieldset/input[@title='Help for Field Label']"), "HelpWindow",
3542                 "http://www.kuali.org/?label_left");
3543 
3544         // test external help of field with label right
3545         assertPopUpWindowUrl(By.xpath("//div[@id='field-label-right-external-help']/fieldset/input[@title='Help for Field Label']"), "HelpWindow",
3546                 "http://www.kuali.org/?label_right");
3547 
3548         // test external help of field with label top and help URL from system parameters
3549         assertPopUpWindowUrl(By.xpath("//div[@id='field-label-top-external-help']/fieldset/input[@title='Help for Field Label']"), "HelpWindow",
3550                 "http://www.kuali.org/?system_parm");
3551 
3552         // test external help of standalone help widget
3553         assertPopUpWindowUrl(By.id("standalone-external-help"), "HelpWindow", "http://www.kuali.org/?widget_only");
3554     }
3555 
3556     /**
3557      * Test the external help on the sub-section and display only fields
3558      */
3559 
3560     protected void testDisplayOnlyExternalHelp2() throws Exception {
3561         // test external help of sub-section
3562         assertPopUpWindowUrl(By.cssSelector("input[title=\"Help for Display only fields\"]"), "HelpWindow", "http://www.kuali.org/?sub_section");
3563 
3564         // test external help of display only data field
3565         assertPopUpWindowUrl(By.xpath(
3566                 "//div[@id='display-field-external-help']/fieldset/input[@title='Help for Field Label']"), "HelpWindow",
3567                 "http://www.kuali.org/?display_field");
3568     }
3569 
3570     /**
3571      * Test the external help on the section and fields with missing help URL
3572      */
3573 
3574     protected void testMissingExternalHelp2() throws Exception {
3575         // test external help of section is not rendered
3576         assertFalse(isElementPresent(By.cssSelector("input[title=\"Help for Missing External Help\"]")));
3577 
3578         // test external help of field with blank externalHelpURL is not rendered
3579         assertFalse(isElementPresentByXpath("//div[@id='external-help-externalHelpUrl-empty']/*[@class='uif-helpImage']"));
3580 
3581         // test external help of field with empty helpDefinition is not rendered
3582         assertFalse(isElementPresentByXpath("//div[@id='external-help-helpdefinition-empty']/*[@class='uif-helpImage']"));
3583 
3584         // test external help of field with missing system parameter is not rendered
3585         assertFalse(isElementPresentByXpath("//div[@id='external-help-system-parm-missing']/*[@class='uif-helpImage']"));
3586 
3587         // test external help of standalone help widget is not rendered
3588         assertFalse(isElementPresentByXpath("//div[@id='standalone-external-help-missing']"));
3589     }
3590 
3591     private String searchForAvailableCode(int codeLength) throws InterruptedException {
3592         String randomCode = RandomStringUtils.randomAlphabetic(codeLength).toUpperCase();
3593         waitAndTypeByName("code", randomCode);
3594         waitAndClickSearch();
3595         int attemptCount = 1;
3596         waitForTextPresent("You have entered the primary key for this table");
3597         while (!isTextPresent("No values match this search.") && attemptCount < 25) {
3598             randomCode = Character.toString((char) (randomCode.toCharArray()[0] + attemptCount++));
3599             clearTextByName("code");
3600             waitAndTypeByName("code", randomCode);
3601             waitAndClickSearch();
3602             waitForTextPresent("You have entered the primary key for this table");
3603         }
3604         return randomCode;
3605     }
3606 
3607     protected void testSearchEditCancel() throws InterruptedException {
3608         selectFrameIframePortlet();
3609         waitAndClickSearch2();
3610         waitAndClickEdit();
3611         testCancelConfirmation();
3612     }
3613 
3614     protected void testServerErrorsIT() throws Exception {
3615         waitAndClickByXpath("//button[contains(.,'Get Error Messages')]");
3616         waitForElementPresent("div[data-messagesfor=\"Demo-ValidationLayout-SectionsPage\"] .uif-errorMessageItem-field");
3617         waitIsVisibleByXpath("//div[@data-header_for='Demo-ValidationLayout-Section1']");
3618         assertElementPresentByXpath("//*[@data-messageitemfor='Demo-ValidationLayout-Section1' and @class='uif-errorMessageItem']");
3619         assertElementPresent("div[data-role=\"InputField\"] img[alt=\"Error\"]");
3620         assertElementPresentByXpath("//a[contains(.,'Section 1 Title')]");
3621         fireMouseOverEventByXpath("//a[contains(.,'Field 1')]");
3622         assertElementPresent(".uif-errorMessageItem-field");
3623         waitAndClickByXpath("//a[contains(.,'Field 1')]");
3624         waitIsVisible(".jquerybubblepopup-innerHtml");
3625         waitIsVisible(".jquerybubblepopup-innerHtml > .uif-serverMessageItems");
3626         waitIsVisible(".jquerybubblepopup-innerHtml > .uif-serverMessageItems .uif-errorMessageItem-field");
3627         waitAndTypeByName("field1", "");
3628         fireEvent("field1", "blur");
3629         fireEvent("field1", "focus");
3630         waitIsVisible(".jquerybubblepopup-innerHtml");
3631         waitIsVisible(".jquerybubblepopup-innerHtml > .uif-serverMessageItems .uif-errorMessageItem-field");
3632         waitIsVisible(".jquerybubblepopup-innerHtml > .uif-clientMessageItems");
3633         waitIsVisible(".jquerybubblepopup-innerHtml > .uif-clientMessageItems  .uif-errorMessageItem-field");
3634         waitAndTypeByName("field1", "t");
3635 
3636         for (int second = 0;; second++) {
3637             if (second >= waitSeconds) {
3638                 jiraAwareFail(TIMEOUT_MESSAGE);
3639             }
3640             try {
3641                 if (!isElementPresent(".jquerybubblepopup-innerHtml > .uif-clientMessageItems")) {
3642                     break;
3643                 }
3644             } catch (Exception e) {}
3645             Thread.sleep(1000);
3646         }
3647 
3648         waitIsVisible(".jquerybubblepopup-innerHtml > .uif-serverMessageItems .uif-errorMessageItem-field");
3649         assertFalse(isElementPresent(".jquerybubblepopup-innerHtml > .uif-clientMessageItems"));
3650     }
3651 
3652     protected void testServerInfoIT() throws Exception {
3653         waitAndClickByXpath("//button[contains(.,'Get Info Messages')]");
3654         waitIsVisibleByXpath("//div[@data-messagesfor='Demo-ValidationLayout-SectionsPage']");
3655         assertTrue(isVisibleByXpath("//div[@data-messagesfor='Demo-ValidationLayout-SectionsPage']"));
3656         assertTrue(isElementPresent("div[data-messagesfor=\"Demo-ValidationLayout-SectionsPage\"] .uif-infoMessageItem"));
3657         assertTrue(isVisible("div[data-messagesfor=\"Demo-ValidationLayout-Section1\"]"));
3658         assertTrue(isElementPresent("div[data-messagesfor=\"Demo-ValidationLayout-Section1\"] .uif-infoMessageItem"));
3659         assertTrue(isElementPresentByXpath("//div[@data-role='InputField']//img[@alt='Information']"));
3660         fireMouseOverEventByXpath("//a[contains(.,'Field 1')]");
3661         assertTrue(isElementPresent(".uif-infoHighlight"));
3662         waitAndClickByXpath("//a[contains(.,'Field 1')]");
3663 
3664         for (int second = 0;; second++) {
3665             if (second >= waitSeconds)
3666                 jiraAwareFail(TIMEOUT_MESSAGE);
3667             try {
3668                 if (isVisible(".jquerybubblepopup-innerHtml"))
3669                     break;
3670             } catch (Exception e) {}
3671             Thread.sleep(1000);
3672         }
3673 
3674         assertTrue(isVisible(".jquerybubblepopup-innerHtml > .uif-serverMessageItems"));
3675         assertTrue(isVisible(".jquerybubblepopup-innerHtml > .uif-serverMessageItems .uif-infoMessageItem-field"));
3676         waitAndTypeByName("field1", "");
3677         fireEvent("field1", "blur");
3678         fireEvent("field1", "focus");
3679 
3680         for (int second = 0;; second++) {
3681             if (second >= waitSeconds)
3682                 jiraAwareFail(TIMEOUT_MESSAGE);
3683             try {
3684                 if (isVisible(".jquerybubblepopup-innerHtml"))
3685                     break;
3686             } catch (Exception e) {}
3687             Thread.sleep(1000);
3688         }
3689 
3690         assertTrue(isVisible(".jquerybubblepopup-innerHtml > .uif-serverMessageItems .uif-infoMessageItem-field"));
3691         for (int second = 0;; second++) {
3692             if (second >= waitSeconds)
3693                 jiraAwareFail(TIMEOUT_MESSAGE);
3694             try {
3695                 if (isVisible(".jquerybubblepopup-innerHtml > .uif-clientMessageItems"))
3696                     break;
3697             } catch (Exception e) {}
3698             Thread.sleep(1000);
3699         }
3700 
3701         assertTrue(isVisible(".jquerybubblepopup-innerHtml > .uif-clientMessageItems  .uif-errorMessageItem-field"));
3702         waitAndTypeByName("field1", "b");
3703         fireEvent("field1", "blur");
3704         fireEvent("field1", "focus");
3705 
3706         for (int second = 0;; second++) {
3707             if (second >= waitSeconds)
3708                 jiraAwareFail(TIMEOUT_MESSAGE);
3709             try {
3710                 if (!isElementPresent(".jquerybubblepopup-innerHtml > .uif-clientMessageItems"))
3711                     break;
3712             } catch (Exception e) {}
3713             Thread.sleep(1000);
3714         }
3715 
3716         fireEvent("field1", "blur");
3717         Thread.sleep(3000);
3718         assertTrue(!isVisible(".jquerybubblepopup-innerHtml > .uif-serverMessageItems .uif-infoMessageItem-field"));
3719         assertFalse(isElementPresent(".jquerybubblepopup-innerHtml > .uif-clientMessageItems"));
3720         fireEvent("field1", "focus");
3721         clearTextByName("field1");
3722         fireEvent("field1", "blur");
3723         assertTrue(isElementPresent("div.uif-hasError"));
3724         assertTrue(isElementPresent("img[src*=\"error.png\"]"));
3725     }
3726 
3727     protected void testServerWarningsIT() throws Exception {
3728         waitAndClickByXpath("//button[contains(.,'Get Warning Messages')]");
3729         waitForPageToLoad();
3730         Thread.sleep(3000);
3731         assertTrue("div[data-messagesfor=\"Demo-ValidationLayout-SectionsPage\"] not visible",
3732                 isVisible("div[data-messagesfor=\"Demo-ValidationLayout-SectionsPage\"]"));
3733         assertTrue("div[data-messagesfor=\"Demo-ValidationLayout-SectionsPage\"] .uif-warningMessageItem not present",
3734                 isElementPresent("div[data-messagesfor=\"Demo-ValidationLayout-SectionsPage\"] .uif-warningMessageItem"));
3735         assertTrue("div[data-messagesfor=\"Demo-ValidationLayout-Section1\"] not visible", isVisible(
3736                 "div[data-messagesfor=\"Demo-ValidationLayout-Section1\"]"));
3737         assertTrue(
3738                 "div[data-messagesfor=\"Demo-ValidationLayout-Section1\"] .uif-warningMessageItem not present",
3739                 isElementPresent("div[data-messagesfor=\"Demo-ValidationLayout-Section1\"] .uif-warningMessageItem"));
3740         assertTrue("div[data-role=\"InputField\"] img[alt=\"Warning\"] not present", isElementPresent(
3741                 "div[data-role=\"InputField\"] img[alt=\"Warning\"]"));
3742         fireMouseOverEvent(By.xpath("//a[contains(.,'Field 1')]"));
3743         assertTrue(".uif-warningHighlight no present when //a[contains(.,'Field 1')] is moused over",
3744                 isElementPresent(".uif-warningHighlight"));
3745         waitAndClickByXpath("//a[contains(.,'Field 1')]");
3746         waitForElementVisible(".jquerybubblepopup-innerHtml", " after click on //a[contains(.,'Field 1')]");
3747         assertTrue(".jquerybubblepopup-innerHtml > .uif-serverMessageItems not visible", isVisible(
3748                 ".jquerybubblepopup-innerHtml > .uif-serverMessageItems"));
3749         assertTrue(".jquerybubblepopup-innerHtml > .uif-serverMessageItems .uif-warningMessageItem-field not visible",
3750                 isVisible(".jquerybubblepopup-innerHtml > .uif-serverMessageItems .uif-warningMessageItem-field"));
3751         waitAndTypeByName("field1", "");
3752         fireEvent("field1", "blur");
3753         fireMouseOverEventByName("field1");
3754         waitForElementVisible(".jquerybubblepopup-innerHtml",
3755                 " not visible after typing nothing in name=field1 then firing blur and focus events");
3756         assertTrue(".jquerybubblepopup-innerHtml > .uif-serverMessageItems .uif-warningMessageItem-field not visible after typing nothing in name=field1 then firing blur and focus events",
3757                 isVisible(".jquerybubblepopup-innerHtml > .uif-serverMessageItems .uif-warningMessageItem-field"));
3758         waitForElementVisible(".jquerybubblepopup-innerHtml> .uif-clientMessageItems",
3759                 " not visible after typing nothing in name=field1 then firing blur and focus events");
3760         assertTrue(".jquerybubblepopup-innerHtml > .uif-clientMessageItems  .uif-errorMessageItem-field not visible after typing nothing in name=field1 then firing blur and focus events",
3761                 isVisible(".jquerybubblepopup-innerHtml > .uif-clientMessageItems  .uif-errorMessageItem-field"));
3762         waitAndTypeByName("field1", "b");
3763         fireEvent("field1", "blur");
3764         fireMouseOverEventByName("field1");
3765         waitForElementVisible(".jquerybubblepopup-innerHtml> .uif-serverMessageItems", "");
3766         assertTrue(".jquerybubblepopup-innerHtml > .uif-serverMessageItems .uif-warningMessageItem-field not visible after typing b in name=field1 then firing blur and focus events",
3767                 isVisible(".jquerybubblepopup-innerHtml > .uif-serverMessageItems .uif-warningMessageItem-field"));
3768         assertTrue(".jquerybubblepopup-innerHtml > .uif-clientMessageItems",
3769                 !isElementPresent(
3770                         ".jquerybubblepopup-innerHtml > .uif-clientMessageItems"));
3771         clearTextByName("field1");
3772         fireEvent("field1", "blur");
3773         fireMouseOverEventByName("field1");
3774         assertTrue(".uif-hasError is not present after typing nothing in name=field1 and then firing focus and blur events",
3775                 isElementPresent(".uif-hasError"));
3776         assertTrue("img[src*=\"error.png\"] is not present after typing nothing in name=field1 and then firing focus and blur events",
3777                 isElementPresent("img[src*=\"error.png\"]"));
3778         passed();
3779     }
3780 
3781     /**
3782      * Test the tooltip and external help on the view
3783      */
3784     protected void testViewHelp() throws Exception {
3785         // test tooltip help
3786         fireEvent("field102", "blur");
3787         fireMouseOverEventByXpath("//h1/span[@class='uif-headerText-span']");
3788         Thread.sleep(500);
3789         assertEquals("Sample text for view help", getTextByXpath("//td[@class='jquerybubblepopup-innerHtml']"));
3790 
3791         // test external help
3792         waitAndClickByXpath("//input[@alt='Help for Configuration Test View - Help']");
3793         Thread.sleep(5000);
3794         switchToWindow("Kuali Foundation");
3795         Thread.sleep(5000);
3796         switchToWindow(CONFIGURATION_VIEW_WINDOW_TITLE);
3797     }
3798 
3799     /**
3800      * Test the tooltip and external help on the view
3801      */
3802     protected void testViewHelp2() throws Exception {
3803         // test tooltip help
3804         if (isElementPresentByXpath("//td[@class='jquerybubblepopup-innerHtml']")) {
3805             assertFalse(findElement(By.cssSelector("td.jquerybubblepopup-innerHtml")).isDisplayed());
3806         }
3807 
3808         // test tooltip help
3809         fireMouseOverEventByXpath("//h1/span[@class='uif-headerText-span']");
3810         Thread.sleep(2000);
3811         assertTrue(isVisibleByXpath("//td[contains(text(),'View help')]"));
3812         assertPopUpWindowUrl(By.cssSelector("input[title=\"Help for Configuration Test View\"]"), "HelpWindow", "http://www.kuali.org/");
3813     }
3814 
3815     protected void testVerifyAddDeleteFiscalOfficerLegacy() throws Exception {
3816         selectFrameIframePortlet();
3817         waitAndTypeByName("document.documentHeader.documentDescription", AutomatedFunctionalTestUtils
3818                 .createUniqueDtsPlusTwoRandomChars());
3819         waitAndTypeByName("newCollectionLines['document.newMaintainableObject.dataObject.fiscalOfficer.accounts'].number","1234567890");
3820         waitAndTypeByName("newCollectionLines['document.newMaintainableObject.dataObject.fiscalOfficer.accounts'].foId", "2");
3821         waitAndClickByXpath("//button[@data-loadingmessage='Adding Line...']");
3822         waitForElementPresentByName("document.newMaintainableObject.dataObject.fiscalOfficer.accounts[0].number");
3823         assertEquals("1234567890", waitAndGetAttributeByName(
3824                 "document.newMaintainableObject.dataObject.fiscalOfficer.accounts[0].number", "value"));
3825         assertEquals("2", waitAndGetAttributeByName(
3826                 "document.newMaintainableObject.dataObject.fiscalOfficer.accounts[0].foId", "value"));
3827         waitAndClickByXpath("//button[@data-loadingmessage='Deleting Line...']");
3828         Thread.sleep(3000);
3829         assertEquals(Boolean.FALSE, (Boolean) isElementPresentByName(
3830                 "document.newMaintainableObject.dataObject.fiscalOfficer.accounts[0].number"));
3831         passed();
3832     }
3833 
3834     protected void testVerifyAddDeleteNoteLegacy() throws Exception {
3835         selectFrameIframePortlet();
3836         waitAndClick("div.tableborders.wrap.uif-boxLayoutVerticalItem.clearfix  span.uif-headerText-span > img.uif-disclosure-image");
3837         waitForElementPresent("button[title='Add a Note'].uif-action.uif-primaryActionButton.uif-smallActionButton");
3838         waitAndClickByName("newCollectionLines['document.notes'].noteText");
3839         waitAndTypeByName("newCollectionLines['document.notes'].noteText", "Test note");
3840         waitAndClick("button[title='Add a Note'].uif-action.uif-primaryActionButton.uif-smallActionButton");
3841         //        waitForElementPresentByName("document.notes[0].noteText");
3842         assertEquals("Test note", getTextByXpath("//pre"));
3843         waitAndClick("button[title='Delete a Note'].uif-action.uif-primaryActionButton.uif-smallActionButton");
3844         assertEquals(Boolean.FALSE, (Boolean) isElementPresentByName("document.notes[0].noteText"));
3845         passed();
3846     }
3847 
3848     protected void testVerifyAdHocRecipientsLegacy() throws Exception {
3849         selectFrameIframePortlet();
3850         waitAndClickByLinkText("Fiscal Officer Accounts");
3851         assertElementPresentByXpath(
3852                 "//select[@name=\"newCollectionLines['document.adHocRoutePersons'].actionRequested\"]");
3853         assertElementPresentByXpath(
3854                 "//input[@name=\"newCollectionLines['document.adHocRoutePersons'].name\" and @type=\"text\"]");
3855         assertElementPresentByXpath(
3856                 "//select[@name=\"newCollectionLines['document.adHocRouteWorkgroups'].actionRequested\"]");
3857         assertElementPresentByXpath(
3858                 "//input[@name=\"newCollectionLines['document.adHocRouteWorkgroups'].recipientNamespaceCode\" and @type='text']");
3859         assertElementPresentByXpath(
3860                 "//input[@name=\"newCollectionLines['document.adHocRouteWorkgroups'].recipientName\" and @type='text']");
3861         passed();
3862     }
3863 
3864     protected void testVerifyButtonsLegacy() throws Exception {
3865         selectFrameIframePortlet();
3866         assertElementPresentByXpath("//button[contains(.,'ubmit')]");
3867         assertElementPresentByXpath("//button[contains(.,'ave')]");
3868         assertElementPresentByXpath("//button[contains(.,'lanket approve')]");
3869         assertElementPresentByXpath("//button[contains(.,'lose')]");
3870         assertElementPresentByXpath("//a[contains(.,'ancel')]");
3871         passed();
3872     }
3873 
3874     protected void testVerifyConstraintText() throws Exception {
3875         selectFrameIframePortlet();
3876         assertEquals("* indicates required field", getText(
3877                 "div.uif-boxLayout.uif-horizontalBoxLayout.clearfix > span.uif-message.uif-requiredInstructionsMessage.uif-boxLayoutHorizontalItem"));
3878         assertEquals("Must not be more than 10 characters", getText(
3879                 "div.uif-group.uif-gridGroup.uif-gridSection.uif-disclosure.uif-boxLayoutVerticalItem.clearfix div[data-label='Travel Account Number'].uif-field.uif-inputField span.uif-message.uif-constraintMessage"));
3880         assertEquals("Must not be more than 10 characters", getText(
3881                 "div.uif-group.uif-gridGroup.uif-gridSection.uif-disclosure.uif-boxLayoutVerticalItem.clearfix div[data-label='Travel Sub Account Number'].uif-field.uif-inputField span.uif-message.uif-constraintMessage"));
3882         assertEquals("Must not be more than 10 characters", getText(
3883                 "div.uif-group.uif-gridGroup.uif-collectionItem.uif-gridCollectionItem.uif-collectionAddItem div[data-label='Travel Account Number'].uif-field.uif-inputField span.uif-message.uif-constraintMessage"));
3884         passed();
3885     }
3886 
3887     protected void testVerifyEditedComponent(String docId, String componentName, String componentCode) throws Exception {
3888         selectFrameIframePortlet();
3889         waitAndTypeByName("name", componentName);
3890         waitAndClickSearch();
3891         isElementPresentByLinkText(componentName);
3892         waitAndClickByLinkText(componentName);
3893         waitForPageToLoad();
3894         Thread.sleep(2000);
3895         switchToWindow("Kuali :: Inquiry");
3896         Thread.sleep(2000);
3897         assertEquals(componentName, getTextByXpath("//div[@class='tab-container']/table//span[@id='name.div']").trim());
3898         assertEquals(componentCode, getTextByXpath("//div[@class='tab-container']/table//span[@id='code.div']").trim());
3899         waitAndClickCloseWindow();
3900         switchToWindow("null");
3901         List<String> parameterList=new ArrayList<String>();
3902     }
3903 
3904     protected void testVerifyDisclosures() throws Exception {
3905         selectFrameIframePortlet();
3906         assertElementPresentByXpath("//span[contains(text(),'Document Overview')]");
3907         assertElementPresentByXpath("//span[contains(text(),'Document Overview')]");
3908         assertElementPresentByXpath("//span[contains(text(),'Account Information')]");
3909         assertElementPresentByXpath("//span[contains(text(),'Fiscal Officer Accounts')]");
3910         assertElementPresentByXpath("//span[contains(text(),'Notes and Attachments')]");
3911         assertElementPresentByXpath("//span[contains(text(),'Ad Hoc Recipients')]");
3912         assertElementPresentByXpath("//span[contains(text(),'Route Log')]");
3913         colapseExpandByXpath("//span[contains(text(),'Document Overview')]//img", "//label[contains(text(),'Organization Document Number')]");
3914         colapseExpandByXpath("//span[contains(text(),'Account Information')]//img","//label[contains(text(),'Travel Account Type Code')]");
3915         colapseExpandByXpath("//span[contains(text(),'Fiscal Officer Accounts')]//img","//a[contains(text(),'Lookup/Add Multiple Lines')]");
3916         expandColapseByXpath("//span[contains(text(),'Notes and Attachments')]//img","//label[contains(text(),'Note Text')]");
3917         expandColapseByXpath("//span[contains(text(),'Ad Hoc Recipients')]","//span[contains(text(),'Ad Hoc Group Requests')]");
3918 
3919         // Handle frames
3920         waitAndClickByXpath("//span[contains(text(),'Route Log')]//img");
3921         selectFrame("routeLogIFrame");
3922         waitIsVisibleByXpath("//img[@alt='refresh']");
3923 
3924         // relative=top iframeportlet might look weird but either alone results in something not found.
3925         selectTopFrame();
3926         selectFrameIframePortlet();
3927         waitAndClickByXpath("//span[contains(text(),'Route Log')]//img");
3928         selectFrame("routeLogIFrame");
3929         waitNotVisibleByXpath("//img[@alt='refresh']");
3930         passed();
3931     }
3932 
3933     protected void testVerifyDocumentOverviewLegacy() throws Exception {
3934         selectFrameIframePortlet();
3935         assertTextPresent("Document Overview");
3936         assertElementPresentByXpath("//input[@name='document.documentHeader.documentDescription']");
3937         assertElementPresentByXpath("//input[@name='document.documentHeader.organizationDocumentNumber']");
3938         assertElementPresentByXpath("//textarea[@name='document.documentHeader.explanation']");
3939         passed();
3940     }
3941 
3942     protected void testVerifyExpandCollapse() throws Exception {
3943         selectFrameIframePortlet();
3944         assertElementPresentByXpath("//button[contains(@class, 'uif-expandDisclosuresButton')]");
3945         assertElementPresentByXpath("//button[contains(@class, 'uif-collapseDisclosuresButton')]");
3946         passed();
3947     }
3948 
3949     protected void testVerifyFieldsLegacy() throws Exception {
3950         selectFrameIframePortlet();
3951         assertElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.number' and @type='text' and @size=10 and @maxlength=10]");
3952         assertElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.extension.accountTypeCode' and @type='text' and @size=2 and @maxlength=3]");
3953         assertElementPresentByXpath(
3954                 "//input[@name='document.newMaintainableObject.dataObject.subAccount' and @type='text' and @size=10 and @maxlength=10]");
3955         assertElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.subsidizedPercent' and @type='text' and @size=6 and @maxlength=20]");
3956         assertElementPresentByXpath(
3957                 "//input[@name='document.newMaintainableObject.dataObject.foId' and @type='text' and @size=5 and @maxlength=10]");
3958         assertElementPresentByXpath(
3959                 "//input[@name=\"newCollectionLines['document.newMaintainableObject.dataObject.fiscalOfficer.accounts'].number\" and @type='text' and @size=10 and @maxlength=10]");
3960         assertElementPresentByXpath(
3961                 "//input[@name=\"newCollectionLines['document.newMaintainableObject.dataObject.fiscalOfficer.accounts'].foId\" and @type='text' and @size=5 and @maxlength=10]");
3962         passed();
3963     }
3964 
3965     protected void testVerifyHeaderFieldsLegacy() throws Exception {
3966         selectFrameIframePortlet();
3967         assertElementPresentByXpath("//div[contains(@class, 'uif-documentNumber')]");
3968         assertElementPresentByXpath("//div[contains(@class, 'uif-documentInitiatorNetworkId')]");
3969         assertElementPresentByXpath("//div[contains(@class, 'uif-documentStatus')]");
3970         assertElementPresentByXpath("//div[contains(@class, 'uif-documentCreateDate')]");
3971         passed();
3972     }
3973 
3974     protected void testVerifyLookupAddMultipleLinesLegacy() throws Exception {
3975         selectFrameIframePortlet();
3976         assertElementPresentByXpath("//a[contains(text(),'Lookup/Add Multiple Lines')]");
3977         passed();
3978     }
3979 
3980     protected void testVerifyNotesAndAttachments() throws Exception {
3981         selectFrameIframePortlet();
3982         waitAndClickByXpath("//span[contains(text(),'Notes and Attachments')]");
3983         waitForElementPresentByXpath("//button[@title='Add a Note']");
3984         assertElementPresentByXpath("//span[contains(text(),'Notes and Attachments')]");
3985         assertElementPresentByXpath("//textarea[@name=\"newCollectionLines['document.notes'].noteText\"]");
3986         assertElementPresentByXpath("//input[@name='attachmentFile']");
3987 
3988         //assertElementPresentByXpath("//input[@name=\"newCollectionLines['document.notes'].attachment.attachmentTypeCode\"]");
3989         passed();
3990     }
3991 
3992     protected void testVerifyQuickfinderIconsLegacy() throws Exception {
3993         selectFrameIframePortlet();
3994         assertTextPresent("Document Overview");
3995         assertElementPresentByXpath("//*[@id='quickfinder1']");
3996         assertElementPresentByXpath("//*[@id='quickfinder2']");
3997         assertElementPresentByXpath("//*[@id='quickfinder3']");
3998         assertElementPresentByXpath("//*[@id='quickfinder4_add']");
3999 
4000         // TODO it would be better to test that the image isn't 404
4001         passed();
4002     }
4003 
4004     protected void testVerifyRouteLog() throws Exception {
4005         selectFrameIframePortlet();
4006         waitAndClickByLinkText("Route Log");
4007         waitForElementPresent("//iframe[contains(@src,'RouteLog.do')]");
4008         passed();
4009     }
4010 
4011     protected void testVerifySave() throws Exception {
4012         selectFrameIframePortlet();
4013         waitAndTypeByName("document.documentHeader.documentDescription", "Test Document " + AutomatedFunctionalTestUtils.DTS);
4014         waitAndClickByName("document.newMaintainableObject.dataObject.number");
4015         waitAndTypeByName("document.newMaintainableObject.dataObject.number", "1234567890");
4016         waitAndTypeByName("document.newMaintainableObject.dataObject.extension.accountTypeCode", "EAT");
4017         waitAndTypeByName("document.newMaintainableObject.dataObject.subAccount", "a1");
4018         waitAndClick(
4019                 "button[data-loadingmessage='Saving...'].uif-action.uif-primaryActionButton.uif-boxLayoutHorizontalItem");
4020         Thread.sleep(2000);
4021 
4022         // checkErrorMessageItem(" also digit validation jira https://jira.kuali.org/browse/KULRICE-8038");
4023         passed();
4024     }
4025 
4026     protected void testVerifySubsidizedPercentWatermarkLegacy() throws Exception {
4027         selectFrameIframePortlet();
4028 
4029         // May be blowing up due to multiple locators
4030         //assertTrue(isElementPresent("//input[@name='document.newMaintainableObject.dataObject.subsidizedPercent' and @type='text' and @placeholder='##.##   ']"));
4031         assertElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.subsidizedPercent']");
4032         passed();
4033     }
4034 
4035     protected void testWorkFlowDocTypeBlanketApprove() throws Exception {
4036         selectFrameIframePortlet();
4037         waitAndCreateNew();
4038         String docId = waitForDocId();
4039         assertBlanketApproveButtonsPresent();
4040         String dts = AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomCharsNot9Digits();
4041         waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Validation Test Document Type " + dts);
4042         String parentDocType = "//input[@name='methodToCall.performLookup.(!!org.kuali.rice.kew.doctype.bo.DocumentType!!).(((name:document.newMaintainableObject.parentDocType.name,documentTypeId:document.newMaintainableObject.docTypeParentId,))).((`document.newMaintainableObject.parentDocType.name:name,`)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;"
4043                 + getBaseUrlString() + "/kr/lookup.do;::::).anchor4']";
4044         waitAndClickByXpath(parentDocType);
4045         waitAndClickSearch();
4046         waitAndClickReturnValue();
4047         String docTypeName = "DocType" + dts;
4048         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.name']", docTypeName);
4049         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.unresolvedDocHandlerUrl']",
4050                 "${kr.url}/maintenance.do?methodToCall=docHandler");
4051         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.label']",
4052                 "Workflow Maintenance Document Type Document " + dts);
4053         waitAndTypeByXpath("//input[@id='document.newMaintainableObject.unresolvedHelpDefinitionUrl']",
4054                 "default.htm?turl=WordDocuments%2Fdocumenttype.htm");
4055         blanketApproveTest(docId);
4056     }
4057 
4058     protected void uncheck(By by) throws InterruptedException {
4059         WebElement element = findElement(by);
4060         if (element.isSelected()) {
4061             element.click();
4062         }
4063     }
4064 
4065     protected void uncheckByName(String name) throws InterruptedException {
4066         uncheck(By.name(name));
4067     }
4068 
4069     protected void uncheckByXpath(String locator) throws InterruptedException {
4070         uncheck(By.xpath(locator));
4071     }
4072 
4073     protected void verifyRichMessagesValidationBasicFunctionality() throws Exception
4074     {
4075         assertTrue(isElementPresentByXpath("//input[@type='text' and @name='field1']"));
4076         assertTrue(isElementPresentByXpath("//a[contains(text(), 'Kuali')]"));
4077         assertTrue(isElementPresentByXpath("//input[@type='checkbox' and @name='field2']"));
4078         Thread.sleep(3000);
4079     }
4080 
4081     protected void verifyRichMessagesValidationAdvancedFunctionality() throws Exception
4082     {
4083         //Color Options
4084         assertTrue(isElementPresentByXpath("//span[@style='color: green;']"));
4085         assertTrue(isElementPresentByXpath("//span[@style='color: blue;']"));
4086 
4087         //Css class
4088         assertTrue(isElementPresentByXpath("//span[@class='fl-text-underline fl-text-larger']"));
4089 
4090         //Combinations
4091         assertTrue(isElementPresentByXpath("//input[@type='text' and @name='field3']"));
4092         assertTrue(isElementPresentByXpath("//select[@name='field4']"));
4093         assertTrue(isElementPresentByXpath("//button[contains(text(), 'Action Button')]"));
4094 
4095         //Rich Message Field
4096         assertTrue(isElementPresentByXpath("//label[contains(., 'Label With')]/span[contains(., 'Color')]"));
4097         assertTrue(isElementPresentByXpath("//label[contains(., 'Label With')]/i/b[contains(., 'Html')]"));
4098         assertTrue(isElementPresentByXpath("//label[contains(., 'Label With')]/img[@class='uif-image inlineBlock']"));
4099         Thread.sleep(3000);
4100     }
4101 
4102     protected void verifyRichMessagesValidationLettersNumbersValidation() throws Exception
4103     {
4104         //For letters only Validation
4105         assertTrue(isElementPresentByXpath("//input[@type='text' and @name='field5']"));
4106         waitAndTypeByXpath(
4107                 "//div[@class='uif-field uif-inputField uif-inputField-labelTop inlineBlock']/input[@name= 'field5']",
4108                 "abc");
4109         assertFalse(isElementPresentByXpath("//div[@class='uif-field uif-inputField uif-inputField-labelTop inlineBlock uif-hasError']"));
4110         clearTextByXpath(
4111                 "//div[@class='uif-field uif-inputField uif-inputField-labelTop inlineBlock']/input[@name= 'field5']");
4112         waitAndTypeByXpath("//div[@class='uif-field uif-inputField uif-inputField-labelTop inlineBlock']/input[@name= 'field5']","abc12");
4113         waitAndTypeByXpath("//input[@name= 'field6']", "");
4114         assertTrue(isElementPresentByXpath("//div[@class='uif-field uif-inputField uif-inputField-labelTop inlineBlock uif-hasError']"));
4115         Thread.sleep(3000);
4116         clearTextByXpath("//div[@class='uif-field uif-inputField uif-inputField-labelTop inlineBlock uif-hasError']/input[@name= 'field5']");
4117         waitAndTypeByXpath("//div[@class='uif-field uif-inputField uif-inputField-labelTop inlineBlock uif-hasError']/input[@name= 'field5']","abc");
4118         waitAndTypeByXpath("//input[@name= 'field6']", "");
4119 
4120         //For numbers only validation
4121         waitAndTypeByXpath("//input[@name= 'field6']", "123");
4122         assertFalse(isElementPresentByXpath("//div[@class='uif-field uif-inputField uif-inputField-labelTop inlineBlock uif-hasError']"));
4123         clearTextByXpath("//input[@name= 'field6']");
4124         waitAndTypeByXpath("//input[@name= 'field6']", "123ab");
4125         fireEvent("field6", "blur");
4126         Thread.sleep(5000);
4127         assertTrue(isElementPresentByXpath("//div[@class='uif-field uif-inputField uif-inputField-labelTop inlineBlock uif-hasError']"));
4128         Thread.sleep(3000);
4129     }
4130 
4131     protected void verifyRichMessagesValidationRadioAndCheckBoxGroupFunctionality() throws Exception
4132     {
4133         //Radio Group
4134         assertTrue(isElementPresentByXpath("//fieldset[@class='uif-verticalRadioFieldset']/span/input[@type='radio' and @name='field24' and @value='1']"));
4135         assertTrue(isElementPresentByXpath(
4136                 "//fieldset[@class='uif-verticalRadioFieldset']/span/input[@type='radio' and @name='field24' and @value='2']"));
4137         assertTrue(isElementPresentByXpath(
4138                 "//fieldset[@class='uif-verticalRadioFieldset']/span/input[@type='radio' and @name='field24' and @value='3']"));
4139         assertTrue(isElementPresentByXpath(
4140                 "//fieldset[@class='uif-verticalRadioFieldset']/span/input[@type='radio' and @name='field24' and @value='4']"));
4141 
4142         //Checkbox Group
4143         assertTrue(isElementPresentByXpath(
4144                 "//fieldset[@class='uif-verticalCheckboxesFieldset']/span/input[@type='checkbox' and @name='field115' and @value='1']"));
4145         assertTrue(isElementPresentByXpath("//fieldset[@class='uif-verticalCheckboxesFieldset']/span/input[@type='checkbox' and @name='field115' and @value='2']"));
4146         assertTrue(isElementPresentByXpath(
4147                 "//fieldset[@class='uif-verticalCheckboxesFieldset']/span/input[@type='checkbox' and @name='field115' and @value='3']"));
4148         assertTrue(isElementPresentByXpath(
4149                 "//fieldset[@class='uif-verticalCheckboxesFieldset']/span/label/div/select[@name='field4']"));
4150 
4151         //Checkbox Control
4152         assertTrue(isElementPresentByXpath("//input[@type='checkbox' and @name='bField1']"));
4153         assertTrue(isElementPresentByXpath("//input[@type='text' and @name='field103']"));
4154     }
4155 
4156     protected void verifyRichMessagesValidationLinkDeclarationsFunctionality() throws Exception
4157     {
4158         //Testing link tag
4159         waitAndClickByXpath("//div[contains(., 'Testing link tag')]/a");
4160         Thread.sleep(9000);
4161         switchToWindow("Open Source Software | www.kuali.org");
4162         switchToWindow(RICH_MESSAGES_WINDOW_TITLE);
4163 
4164         //Testing methodToCall Action
4165         waitAndClickByXpath("//div[contains(., 'Testing methodToCall action')]/a");
4166         Thread.sleep(3000);
4167         assertTrue(isElementPresentByXpath(
4168                 "//div[@class='uif-validationMessages uif-groupValidationMessages uif-pageValidationMessages uif-pageValidationMessages-error']"));
4169         assertTrue(isElementPresentByXpath(
4170                 "//div[@id='Demo-AdvancedMessagesSection']/div[@class='uif-validationMessages uif-groupValidationMessages uif-pageValidationMessages-error']"));
4171         assertTrue(isElementPresentByXpath("//div[@id='Demo-RadioCheckboxMessageSection']/div[@class='uif-validationMessages uif-groupValidationMessages uif-pageValidationMessages-error']"));
4172 
4173         //Testing methodToCall action (no client validation check)
4174         waitAndClickByXpath("//div[contains(., 'Testing methodToCall action (no client validation check)')]/a");
4175         assertTrue(isElementPresentByXpath("//div[@class='uif-validationMessages uif-groupValidationMessages uif-pageValidationMessages uif-pageValidationMessages-error']"));
4176         assertTrue(isElementPresentByXpath("//div[@class='uif-validationMessages uif-groupValidationMessages']"));
4177         assertTrue(isElementPresentByXpath("//div[@class='uif-validationMessages uif-groupValidationMessages uif-pageValidationMessages uif-pageValidationMessages-error']"));
4178         assertTrue(isElementPresentByXpath("//div[@id='Demo-AdvancedMessagesSection']/div[@class='uif-validationMessages uif-groupValidationMessages uif-pageValidationMessages-error']"));
4179         assertTrue(isElementPresentByXpath("//div[@id='Demo-RadioCheckboxMessageSection']/div[@class='uif-validationMessages uif-groupValidationMessages uif-pageValidationMessages-error']"));
4180         Thread.sleep(3000);
4181     }
4182 
4183     protected void waitAndClickAdministration() throws InterruptedException {
4184         waitAndClickByLinkText(ADMINISTRATION_LINK_TEXT, this);
4185     }
4186 
4187     /**
4188      * {@link #ADMINISTRATION_LINK_TEXT}
4189      * @param failable
4190      * @throws InterruptedException
4191      */
4192     private void waitAndClickAdministration(JiraAwareFailable failable) throws InterruptedException {
4193         waitAndClickByLinkText(ADMINISTRATION_LINK_TEXT, failable);
4194     }
4195 
4196     protected void waitAndCancelConfirmation() throws InterruptedException {
4197         waitAndClickCancel();
4198         waitAndClickByName("methodToCall.processAnswer.button0");
4199     }
4200 
4201     protected void waitAndClick(By by) throws InterruptedException {
4202         jiraAwareWaitAndClick(by, this.getClass().toString());
4203     }
4204 
4205     protected void waitAndClick(By by, JiraAwareFailable failable) throws InterruptedException {
4206         jiraAwareWaitAndClick(by, this.getClass().toString(), failable);
4207     }
4208 
4209     protected void waitAndClick(String locator, String message) throws InterruptedException {
4210         jiraAwareWaitAndClick(By.cssSelector(locator), message);
4211     }
4212 
4213     protected void waitAndClickById(String id) throws InterruptedException {
4214         jiraAwareWaitAndClick(By.id(id), this.getClass().toString());
4215     }
4216 
4217     protected void waitAndClickById(String id, String message) throws InterruptedException {
4218         jiraAwareWaitAndClick(By.id(id), message);
4219     }
4220 
4221     protected void waitAndClickByLinkText(String text) throws InterruptedException {
4222         waitAndClickByLinkText(text, this.getClass().toString());
4223     }
4224 
4225     protected void waitAndClickByLinkText(String text, String message) throws InterruptedException {
4226         waitAndClickByLinkText(text, message, this);
4227     }
4228 
4229     protected void waitAndClickByLinkText(String text, JiraAwareFailable failable) throws InterruptedException {
4230         waitAndClickByLinkText(text, this.getClass().toString(), failable);
4231     }
4232 
4233     protected void waitAndClickByLinkText(String text, String message, JiraAwareFailable failable) throws InterruptedException {
4234         jGrowl("Click " + text + " link.");
4235         jiraAwareWaitAndClick(By.linkText(text), message, failable);
4236     }
4237 
4238     protected void waitAndClickLinkContainingText(String linkText) throws InterruptedException {
4239         waitAndClickLinkContainingText(linkText, this.getClass().toString());
4240     }
4241 
4242     protected void waitAndClickLinkContainingText(String linkText, String message) throws InterruptedException {
4243         jGrowl("Click link containing " + linkText + " .");
4244         waitAndClickByXpath("//a[contains(text(), '" + linkText + "')]", message);
4245     }
4246 
4247     protected void waitAndClickByName(String name) throws InterruptedException {
4248         jGrowl("Click By Name " + name);
4249         jiraAwareWaitAndClick(By.name(name), this.getClass().toString());
4250     }
4251 
4252     protected void waitAndClickByValue(String value) throws InterruptedException {
4253         waitAndGetElementByAttributeValue("value", value).click();
4254     }
4255 
4256     protected void waitAndClickByXpath(String xpath) throws InterruptedException {
4257         waitAndClick(By.xpath(xpath));
4258     }
4259 
4260     protected void waitAndClickByXpath(String xpath, JiraAwareFailable failable) throws InterruptedException {
4261         waitAndClick(By.xpath(xpath), failable);
4262     }
4263 
4264     protected void waitAndClickByName(String name, String message) throws InterruptedException {
4265         jiraAwareWaitAndClick(By.name(name), message);
4266     }
4267 
4268     protected void waitAndClickByXpath(String xpath, String message) throws InterruptedException {
4269         jiraAwareWaitAndClick(By.xpath(xpath), message);
4270     }
4271 
4272     protected void waitAndClickButtonByText(String buttonText) throws InterruptedException {
4273         waitAndClickButtonByText(buttonText, this.getClass().toString());
4274     }
4275 
4276     protected void waitAndClickButtonByText(String buttonText, String message) throws InterruptedException {
4277         jGrowl("Click " + buttonText + " button.");
4278         waitAndClickByXpath("//button[contains(text(), '" + buttonText + "')]", message);
4279     }
4280 
4281     protected void waitAndClickAllByName(String name) throws InterruptedException{
4282         List<WebElement> elements = driver.findElements(By.name(name));
4283         for(WebElement ele : elements){
4284             ele.click();
4285         }
4286     }
4287 
4288     /**
4289      * {@link #CANCEL_NAME}
4290      * @throws InterruptedException
4291      */
4292     protected void waitAndClickCancel() throws InterruptedException {
4293         waitAndClickByName(CANCEL_NAME);
4294     }
4295 
4296     /**
4297      * {@link #CLOSE_WINDOW_XPATH_TITLE}
4298      * @throws InterruptedException
4299      */
4300     protected void waitAndClickCloseWindow() throws InterruptedException {
4301         waitAndClickByXpath(CLOSE_WINDOW_XPATH_TITLE);
4302     }
4303 
4304     /**
4305      * {@link #COPY_LINK_TEXT}
4306      * @throws InterruptedException
4307      */
4308     protected void waitAndClickCopy() throws InterruptedException {
4309         waitAndClickByLinkText(COPY_LINK_TEXT);
4310     }
4311 
4312     /**
4313      * {}@link #DOC_SEARCH_XPATH}
4314      * @throws InterruptedException
4315      */
4316     protected void waitAndClickDocSearch() throws InterruptedException {
4317         waitAndClickByXpath(DOC_SEARCH_XPATH);
4318     }
4319 
4320     /**
4321      * {@link #DOC_SEARCH_XPATH_TITLE}
4322      * @throws InterruptedException
4323      */
4324     protected void waitAndClickDocSearchTitle() throws InterruptedException {
4325         waitAndClickByXpath(DOC_SEARCH_XPATH_TITLE);
4326     }
4327 
4328     /**
4329      * {@link #LOGOUT_XPATH}
4330      * @throws InterruptedException
4331      */
4332     protected void waitAndClickLogout() throws InterruptedException {
4333         waitAndClickLogout(this);
4334     }
4335 
4336     /**
4337      * {@link #LOGOUT_XPATH}
4338      * @param failable
4339      * @throws InterruptedException
4340      */
4341     protected void waitAndClickLogout(JiraAwareFailable failable) throws InterruptedException {
4342         jGrowl("Logging out");
4343         selectTopFrame();
4344         waitAndClickByXpath(LOGOUT_XPATH, failable);
4345     }
4346 
4347     protected void waitAndClickLogoutIfPresent() throws InterruptedException {
4348         selectTopFrame();
4349         if (isElementPresentByXpath(LOGOUT_XPATH)) {
4350             waitAndClickLogout(this);
4351         }
4352     }
4353 
4354     protected void waitAndClickMainMenu() throws InterruptedException {
4355         waitAndClickByLinkText(MAIN_MENU_LINK_TEXT, this);
4356     }
4357 
4358     /**
4359      * {}@link #MAIN_MENU_LINK_TEXT}
4360      * @param failable
4361      * @throws InterruptedException
4362      */
4363     private void waitAndClickMainMenu(JiraAwareFailable failable) throws InterruptedException {
4364         waitAndClickByLinkText(MAIN_MENU_LINK_TEXT, failable);
4365     }
4366 
4367     /**
4368      * {@link #SAVE_XPATH}
4369      * @throws InterruptedException
4370      */
4371     protected void waitAndClickSave() throws InterruptedException {
4372         waitAndClickByXpath(SAVE_XPATH);
4373     }
4374 
4375     /**
4376      * {@link #SUBMIT_XPATH}
4377      * @throws InterruptedException
4378      */
4379     protected void waitAndClickSubmit() throws InterruptedException {
4380         waitAndClickByXpath(SUBMIT_XPATH);
4381     }
4382 
4383     /**
4384      * {@link #XML_INGESTER_LINK_TEXT}
4385      * @param failable
4386      * @throws InterruptedException
4387      */
4388     protected void waitAndClickXMLIngester(JiraAwareFailable failable) throws InterruptedException {
4389         waitAndClickByLinkText(XML_INGESTER_LINK_TEXT, failable);
4390     }
4391 
4392     protected void waitAndSelectByName(String name, String selectText) throws InterruptedException {
4393         waitFor(By.name(name), selectText + " not found.");
4394         select(By.name(name), selectText);
4395     }
4396 
4397     protected WebElement waitAndType(By by, String text) throws InterruptedException {
4398         return waitAndType(by, text, this.getClass().toString());
4399     }
4400 
4401     protected WebElement waitAndType(String selector, String text) throws InterruptedException {
4402         return waitAndType(By.cssSelector(selector), text);
4403     }
4404 
4405     protected WebElement waitAndTypeById(String id, String text) throws InterruptedException {
4406         return waitAndType(By.id(id), text);
4407     }
4408 
4409     protected WebElement waitAndTypeByXpath(String locator, String text) throws InterruptedException {
4410         return waitAndType(By.xpath(locator), text);
4411     }
4412 
4413     protected WebElement waitAndTypeByXpath(String locator, String text, String message) throws InterruptedException {
4414         return waitAndType(By.xpath(locator), text, message);
4415     }
4416 
4417     protected WebElement waitAndTypeByName(String name, String text) throws InterruptedException {
4418         return waitAndType(By.name(name), text);
4419     }
4420 
4421     protected void waitAndCreateNew() throws InterruptedException {
4422         waitAndCreateNew(this.getClass().toString());
4423     }
4424 
4425     protected void waitAndCreateNew(String message) throws InterruptedException {
4426         selectFrameIframePortlet();
4427         jGrowl("Create New");
4428         waitAndClickCreateNew(message);
4429     }
4430 
4431     /**
4432      * {@link #CREATE_NEW_XPATH}
4433      * @throws InterruptedException
4434      */
4435     protected void waitAndClickCreateNew() throws InterruptedException {
4436         waitAndClickCreateNew(this.getClass().toString());
4437     }
4438 
4439     protected void waitAndClickCreateNew(String message) throws InterruptedException {
4440         jGrowl("Click Create New");
4441         if (WebDriverUtils.waitFors(driver, By.xpath(CREATE_NEW_XPATH)).size() > 0) {
4442             waitAndClickByXpath(CREATE_NEW_XPATH, message);
4443         } else {
4444             System.out.println("waitAndClickByXpath(" + CREATE_NEW_XPATH + ") wasn't found trying " + CREATE_NEW_XPATH2);
4445             waitAndClickByXpath(CREATE_NEW_XPATH2, message);
4446         }
4447     }
4448 
4449     protected void waitAndClickDropDown(String dropDownText) throws InterruptedException {
4450         jGrowl("Click the " + dropDownText + " drop down.");
4451         WebElement dropdownMenu = waitAndGetElementByAttributeValue("class", "dropdown-toggle");
4452         Thread.sleep(1000);
4453         dropdownMenu.click();
4454         waitAndClickByLinkText(dropDownText, "dropdown click " + dropDownText + " problem");
4455     }
4456 
4457     protected void waitAndClickEdit() throws InterruptedException {
4458         waitAndClickByLinkText(EDIT_LINK_TEXT);
4459     }
4460 
4461     protected void waitAndClickReturnValue() throws InterruptedException {
4462         waitAndClickByLinkText(RETURN_VALUE_LINK_TEXT, "Unable to click return value " + this.getClass().toString());
4463     }
4464 
4465     protected void waitAndClickReturnValue(String message) throws InterruptedException {
4466         waitAndClickByLinkText(RETURN_VALUE_LINK_TEXT, message);
4467     }
4468 
4469     /**
4470      * {@link #SEARCH_XPATH}
4471      * @throws InterruptedException
4472      */
4473     protected void waitAndClickSearch() throws InterruptedException {
4474         jGrowl("Click Search");
4475         waitAndClickByXpath(SEARCH_XPATH);
4476     }
4477 
4478     protected void waitAndClickSearch2() throws InterruptedException {
4479         jGrowl("Click Search");
4480         waitAndClickByXpath(SEARCH_XPATH_2);
4481     }
4482 
4483     protected void waitAndClickSearch3() throws InterruptedException {
4484         jGrowl("Click Search");
4485         waitAndClickByXpath(SEARCH_XPATH_3);
4486     }
4487 
4488     protected void waitAndClickSearchSecond() throws InterruptedException {
4489         jGrowl("Click Search");
4490         waitAndClickByXpath(SEARCH_SECOND);
4491     }
4492 
4493     protected String waitForDocId() throws InterruptedException {
4494         checkForDocError();
4495         waitForElementPresentByXpath(DOC_ID_XPATH);
4496 
4497         return findElement(By.xpath(DOC_ID_XPATH)).getText();
4498     }
4499 
4500     protected String waitForDocInitiator() throws InterruptedException {
4501         waitForElementPresentByXpath(DOC_INITIATOR_XPATH);
4502 
4503         return findElement(By.xpath(DOC_INITIATOR_XPATH)).getText();
4504     }
4505 
4506     protected String waitForDocStatus() throws InterruptedException {
4507         waitForElementPresentByXpath(DOC_STATUS_XPATH);
4508 
4509         return findElement(By.xpath(DOC_STATUS_XPATH)).getText();
4510     }
4511 
4512     protected WebElement waitForElementPresent(By by) throws InterruptedException {
4513         return jiraAwareWaitFor(by, this.getClass().toString());
4514     }
4515 
4516     protected WebElement waitForElementPresent(By by, String message) throws InterruptedException {
4517         return jiraAwareWaitFor(by, message);
4518     }
4519 
4520     protected WebElement waitForElementPresent(String locator) throws InterruptedException {
4521         return jiraAwareWaitFor(By.cssSelector(locator), this.getClass().toString());
4522     }
4523 
4524     protected WebElement waitForElementPresentByClassName(String name) throws InterruptedException {
4525         return jiraAwareWaitFor(By.className(name), this.getClass().toString());
4526     }
4527 
4528     protected WebElement waitForElementPresentByClassName(String name, String message) throws InterruptedException {
4529         return jiraAwareWaitFor(By.className(name), message);
4530     }
4531 
4532     protected WebElement waitForElementPresentByClassName(String name, int seconds) throws InterruptedException {
4533         return jiraAwareWaitFor(By.className(name), seconds, this.getClass().toString());
4534     }
4535 
4536     protected void waitForElementsPresentByClassName(String name, String message) throws InterruptedException {
4537         jiraAwareWaitFors(By.className(name), message);
4538     }
4539 
4540     protected WebElement waitForElementPresentById(String id) throws InterruptedException {
4541         return jiraAwareWaitFor(By.id(id), this.getClass().toString());
4542     }
4543 
4544     protected void waitForElementPresentById(String id, String message) throws InterruptedException {
4545         jiraAwareWaitFor(By.id(id), message);
4546     }
4547 
4548     protected void waitForElementPresentById(String id, String message, int seconds) throws InterruptedException {
4549         jiraAwareWaitFor(By.id(id), seconds, message);
4550     }
4551 
4552     protected void waitForElementsPresentById(String id, String message) throws InterruptedException {
4553         jiraAwareWaitFors(By.id(id), message);
4554     }
4555 
4556     protected WebElement waitForElementPresentByName(String name) throws InterruptedException {
4557         return waitForElementPresentByName(name, this.getClass().toString());
4558     }
4559 
4560     protected WebElement waitForElementPresentByName(String name, String message) throws InterruptedException {
4561         return jiraAwareWaitFor(By.name(name), message);
4562     }
4563 
4564     protected WebElement waitForElementPresentByXpath(String xpath) throws InterruptedException {
4565         return jiraAwareWaitFor(By.xpath(xpath), this.getClass().toString());
4566     }
4567 
4568     protected WebElement waitForElementPresentByXpath(String xpath, String message) throws InterruptedException {
4569         return jiraAwareWaitFor(By.xpath(xpath), message);
4570     }
4571 
4572     protected void waitForElementsPresentByXpath(String xpathLocator) throws InterruptedException {
4573         jiraAwareWaitFors(By.xpath(xpathLocator), this.getClass().toString());
4574     }
4575 
4576     protected void waitForElementNotPresent(By by) throws InterruptedException {
4577         driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
4578         int secondsToWait = WebDriverUtils.configuredImplicityWait() * 1000;
4579         while (isElementPresent(by) && secondsToWait > 0) {
4580             secondsToWait -= 1000;
4581             Thread.sleep(1000);
4582         }
4583         if (isElementPresent(by)) {
4584             jiraAwareFail(by + " is still present");
4585         }
4586         driver.manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
4587     }
4588 
4589     protected boolean waitForIsTextPresent(String text) throws InterruptedException {
4590         boolean present = false;
4591         driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
4592         int secondsToWait = WebDriverUtils.configuredImplicityWait() * 1000;
4593         while (!isTextPresent(text) && secondsToWait > 0) {
4594             secondsToWait -= 1000;
4595             Thread.sleep(1000);
4596         }
4597         if (isTextPresent(text)) {
4598             present = true;
4599         }
4600         driver.manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
4601         return present;
4602     }
4603 
4604     protected void waitForTextPresent(String text) throws InterruptedException {
4605         driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
4606         int secondsToWait = WebDriverUtils.configuredImplicityWait() * 1000;
4607         while (!isTextPresent(text) && secondsToWait > 0) {
4608             secondsToWait -= 1000;
4609             Thread.sleep(1000);
4610         }
4611         if (!isTextPresent(text)) {
4612             jiraAwareFail(text + " is not present for " + this.getClass().toString());
4613         }
4614         driver.manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
4615     }
4616 
4617     protected void waitForTextPresent(String text, int secondsToWait) throws InterruptedException {
4618         driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
4619         while (!isTextPresent(text) && secondsToWait > 0) {
4620             secondsToWait -= 1000;
4621             Thread.sleep(1000);
4622         }
4623         if (!isTextPresent(text)) {
4624             jiraAwareFail(text + " is not present for " + this.getClass().toString());
4625         }
4626         driver.manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
4627     }
4628 
4629     protected void waitForTextNotPresent(String text) throws InterruptedException {
4630         driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
4631         int secondsToWait = WebDriverUtils.configuredImplicityWait() * 1000;
4632         while (isTextPresent(text) && secondsToWait > 0) {
4633             secondsToWait -= 1000;
4634             Thread.sleep(1000);
4635         }
4636         if (isTextPresent(text)) {
4637             jiraAwareFail(text + " is still present for " + this.getClass().toString());
4638         }
4639         driver.manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
4640     }
4641 
4642     protected void waitForTitleToEqualKualiPortalIndex() throws InterruptedException {
4643         waitForTitleToEqualKualiPortalIndex(this.getClass().toString());
4644     }
4645 
4646     protected void waitIsVisible(By by) throws InterruptedException {
4647         driver.manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
4648         isVisible(by);
4649         driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
4650 
4651         //        for (int second = 0;; second++) {
4652         //            if (second >= waitSeconds) {
4653         //                jiraAwareFail(TIMEOUT_MESSAGE + " " + by.toString());
4654         //            }
4655         //            if (isVisible(by)) {
4656         //                break;
4657         //            }
4658         //            Thread.sleep(1000);
4659         //        }
4660     }
4661 
4662     protected void waitIsVisible(By by, String message) throws InterruptedException {
4663         for (int second = 0;; second++) {
4664             if (second >= waitSeconds) {
4665                 jiraAwareFail(TIMEOUT_MESSAGE + " " + by.toString() + " " + message);
4666             }
4667             if (isVisible(by)) {
4668                 break;
4669             }
4670             Thread.sleep(1000);
4671         }
4672     }
4673 
4674     protected boolean waitAreAnyVisible(By[] bys) throws InterruptedException {
4675         if (bys == null || bys.length == 0 ) {
4676             return false;
4677         }
4678 
4679         for (int second = 0; second < waitSeconds; second++) {
4680 
4681             if (isVisible(bys)) {
4682                 return true;
4683             }
4684 
4685             Thread.sleep(1000);
4686         }
4687 
4688         return false;
4689     }
4690 
4691     protected boolean isVisible(By[] bys) {
4692         if (bys == null || bys.length == 0 ) {
4693             return false;
4694         }
4695 
4696         for (int i = 0, s = bys.length; i < s; i++) {
4697 
4698             try {
4699 
4700                 if (isVisible(bys[i])) {
4701                     return true;
4702                 }
4703 
4704             } catch (NoSuchElementException nsee) {
4705                 // don't fail
4706             }
4707 
4708         }
4709 
4710         return false;
4711     }
4712 
4713     /**
4714      * Uses Selenium's findElements method which does not throw a test exception if not found.
4715      * @param elementLocator
4716      * @param message
4717      * @throws InterruptedException
4718      */
4719     protected void waitForElementVisible(String elementLocator, String message) throws InterruptedException {
4720         waitForElementVisibleBy(By.cssSelector(elementLocator), message);
4721     }
4722 
4723     protected WebElement waitForElementVisibleBy(By by, String message) throws InterruptedException {
4724         driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
4725 
4726         boolean failed = false;
4727 
4728         for (int second = 0;; second++) {
4729             if (second >= waitSeconds)
4730                 failed = true;
4731             try {
4732                 if (failed || (driver.findElements(by)).size() > 0)
4733                     break;
4734             } catch (Exception e) {}
4735             Thread.sleep(1000);
4736         }
4737 
4738         checkForIncidentReport(by.toString()); // after timeout to be sure page is loaded
4739 
4740         driver.manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
4741 
4742         if (failed) {
4743             jiraAwareFail("timeout of " + waitSeconds + " seconds waiting for " + by + " " + message + " " + driver
4744                     .getCurrentUrl());
4745             return null;
4746         }
4747         return driver.findElements(by).get(0);
4748     }
4749 
4750     protected void waitForElementVisibleById(String id, String message) throws InterruptedException {
4751         waitForElementVisibleBy(By.id(id), message);
4752     }
4753 
4754     protected void waitIsVisible(String locator) throws InterruptedException {
4755         waitIsVisible(By.cssSelector(locator));
4756     }
4757 
4758     protected void waitIsVisibleByXpath(String locator) throws InterruptedException {
4759         waitIsVisible(By.xpath(locator));
4760     }
4761 
4762     protected void waitIsVisibleByXpath(String locator, String message) throws InterruptedException {
4763         waitIsVisible(By.xpath(locator), message);
4764     }
4765 
4766     protected void waitForTitleToEqualKualiPortalIndex(String message) throws InterruptedException {
4767         Thread.sleep(2000);
4768         // This started failing in CI....
4769         // boolean failed = false;
4770         //
4771         // for (int second = 0;; second++) {
4772         //     Thread.sleep(1000);
4773         //     if (second >= waitSeconds) failed = true;
4774         //     try { if (failed || ITUtil.KUALI_PORTAL_TITLE.equals(driver.getTitle())) break; } catch (Exception e) {}
4775         // }
4776 
4777         // WebDriverUtils.checkForIncidentReport(driver, message); // after timeout to be sure page is loaded
4778         // if (failed) jiraAwareFail("timeout of " + waitSeconds + " seconds " + message);
4779     }
4780 
4781     protected void waitAndClick(String locator) throws InterruptedException {
4782         waitAndClick(locator, this.getClass().toString());
4783     }
4784 
4785     /**
4786      * {@deprecated} use any of the various wait methods over this, waitForElementPresent for example.
4787      * @throws InterruptedException
4788      */
4789     protected void waitForPageToLoad() throws InterruptedException {
4790         Thread.sleep(5000);
4791     }
4792 
4793     protected WebElement waitFor(By by) throws InterruptedException {
4794         return jiraAwareWaitFor(by, this.getClass().toString());
4795     }
4796 
4797     /**
4798      * Should be called from jiraAwareWaitFor to get KULRICE error output in CI.
4799      *
4800      * Inner most waitFor, let it throw the failure so the timeout message reflects the waitSeconds time, not the 1
4801      * second it is set to before returning.
4802      * @param by
4803      * @param message
4804      * @throws InterruptedException
4805      */
4806     protected void waitFor(By by, String message) throws InterruptedException {
4807         WebDriverUtils.waitFor(this.driver, this.waitSeconds, by, message);
4808     }
4809 
4810     /**
4811      * {@link #KRAD_XPATH}
4812      * @throws InterruptedException
4813      */
4814     protected void waitAndClickKRAD() throws InterruptedException {
4815         waitAndClickByLinkText(KRAD_XPATH);
4816     }
4817 
4818     protected void waitNotVisible(By by) throws InterruptedException {
4819         for (int second = 0;; second++) {
4820             if (second >= waitSeconds) {
4821                 jiraAwareFail(TIMEOUT_MESSAGE);
4822             }
4823             if (!isVisible(by)) {
4824                 break;
4825             }
4826             Thread.sleep(1000);
4827         }
4828     }
4829 
4830     protected void waitNotVisibleByXpath(String locator) throws InterruptedException {
4831         waitNotVisible(By.xpath(locator));
4832     }
4833 
4834     /**
4835      * Does the test page use KRAD UIF?
4836      * Useful if trying to re-use a test for both a KNS and KRAD screens that have different paths to the elements.
4837      * @return
4838      */
4839     protected boolean isKrad(){
4840         return (AutomatedFunctionalTestUtils.REMOTE_UIF_KRAD.equalsIgnoreCase(getUiFramework()));
4841     }
4842 
4843     protected WebElement getElementByAttribute(String attributeName){
4844         return findElement(By.cssSelector("[" + attributeName + "]"));
4845     }
4846 
4847     protected WebElement getElementByDataAttribute(String dataAttributeName){
4848         return findElement(By.cssSelector("[data-" + dataAttributeName + "]"));
4849     }
4850 
4851     protected WebElement getElementByDataAttributeValue(String dataAttributeName, String value){
4852         return findElement(By.cssSelector("[data-" + dataAttributeName + "='" + value +"']"));
4853     }
4854 
4855     protected WebElement getElementByAttributeValue(String attributeName, String value){
4856         return findElement(By.cssSelector("[" + attributeName + "='" + value +"']"));
4857     }
4858 
4859     protected List<WebElement> getElementsByAttributeValue(String attributeName, String value){
4860         return findElements(By.cssSelector("[" + attributeName + "='" + value +"']"));
4861     }
4862 
4863     /**
4864      * Returns the label text of a label-for element
4865      * <p>
4866      * For usage with elements like this: <label for="some-element-id">The text of the Label</label>
4867      * </p>
4868      *
4869      * @param forElementId the id of the element for which to find the label text
4870      * @return label text
4871      */
4872     protected String getForLabelText(String forElementId) {
4873         return findElement(By.cssSelector("label[for=" + forElementId + "]")).getText();
4874     }
4875 
4876     /**
4877      * Determines whether KRAD or KNS UIF is used for this test.
4878      * Useful if trying to re-use a test for both a KNS and KRAD screens that have different paths to the elements.
4879      * @return
4880      */
4881     public String getUiFramework() {
4882         return uiFramework;
4883     }
4884 
4885     /**
4886      * Sets which UIF is used by this test
4887      */
4888     public void setUiFramework(String uiFramework) {
4889         this.uiFramework = uiFramework;
4890     }
4891 }