001/**
002 * Copyright 2005-2015 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.testtools.selenium;
017
018import org.openqa.selenium.Keys;
019
020import org.apache.commons.lang.RandomStringUtils;
021import org.junit.Before;
022import org.kuali.rice.testtools.common.JiraAwareFailable;
023import org.kuali.rice.testtools.common.JiraAwareFailureUtils;
024import org.kuali.rice.testtools.common.PropertiesUtils;
025import org.openqa.selenium.By;
026import org.openqa.selenium.WebElement;
027
028import java.io.IOException;
029import java.text.SimpleDateFormat;
030import java.util.ArrayList;
031import java.util.Calendar;
032import java.util.HashMap;
033import java.util.List;
034import java.util.Map;
035import java.util.concurrent.TimeUnit;
036
037/**
038 * <p>
039 * Old rice sampleapp AFT code.  New KRAD AFT code should go in WebDriverAftBase (or maybe KradAftBase in the future).
040 * </p>
041 * <p>
042 * Originally used to upgrade UpgradedSeleniumITBase (Selenium 1.0) tests to WebDriver (Selenium 2.0).  Now there is
043 * refactoring to be done:
044 * <ol>
045 *   <li><a href="https://jira.kuali.org/browse/KULRICE-9206">KULRICE-9206</a> Replace literal strings used more than 3 times with Constants,
046 *   Javadoc constant with constant value.
047 *   <li>Extract duplicate waitAndClick...(CONSTANT) to waitAndClickConstant, Javadoc a <pre>{@link &#35;CONSTANT}</pre>.
048 *   <li>Replace large chunks of duplication</li>
049 *   <li><a href="https://jira.kuali.org/browse/KULRICE-9205">KULRICE-9205</a> Invert dependencies on fields and extract methods to WebDriverUtils
050 *   so inheritance doesn't have to be used for reuse.  See WebDriverUtils.waitFor </li>
051 *   <li>Extract Nav specific code?</li>
052 *   <li>Rename to SampleAppAftBase</li>
053 * </ol>
054 * </p>
055 * <p>Calls to passed() probably don't belong in the methods reused here.</p>
056 * @author Kuali Rice Team (rice.collab@kuali.org)
057 * @deprecated only rice sampleapp specific code should go in this class, see WebDriverAftBase.
058 */
059@Deprecated
060public abstract class WebDriverLegacyITBase extends WebDriverAftBase {
061
062    /**
063     * Administration
064     */
065    public static final String ADMINISTRATION_LINK_TEXT = "Administration";
066
067    /**
068     * Agenda Lookup
069     */
070    public static final String AGENDA_LOOKUP_LINK_TEXT = "Agenda Lookup";
071
072    /**
073     * backdoorId
074     */
075    public static final String BACKDOOR_ID_TEXT = "backdoorId";
076
077    /**
078     * "//input[@title='Click to login.']"
079     */
080    public static final String BACKDOOR_LOGIN_BUTTON_XPATH = "//input[@title='Click to login.']";
081
082    /**
083     * methodToCall.blanketApprove
084     */
085    public static final String BLANKET_APPROVE_NAME = "methodToCall.blanketApprove";
086
087    /**
088     * methodToCall.cancel
089     * different cancel than CANCEL2_XPATH
090     */
091    public static final String CANCEL_NAME = "methodToCall.cancel";
092
093    /**
094     * //a[contains(text(), 'ancel')]
095     * Different cancel than CANCEL_NAME
096     */
097    public static final String CANCEL2_XPATH = "//a[contains(text(), 'ancel')]";
098
099    /**
100     * "//a[@title='cancel']"
101     */
102    public static final String CANCEL3_XPATH = "//a[@title='cancel']";
103
104    /**
105     * //*[@title='close this window']
106     */
107    public static final String CLOSE_WINDOW_XPATH_TITLE = "//*[@title='close this window']";
108
109    /**
110     * Collections
111     */
112    public static final String COLLECTIONS_LINK_TEXT = "Collections";
113
114    /**
115     * "Kuali :: Configuration Test View"
116     */
117    public static final String CONFIGURATION_VIEW_WINDOW_TITLE = "Kuali :: Configuration Test View";
118
119    /**
120     * (//a[contains(text(),'Configuration Test View')])[3]
121     */
122    public static final String CONFIGURATION_VIEW_XPATH = "(//a[contains(text(),'Configuration Test View')])";
123
124    /**
125     * copy
126     */
127    public static final String COPY_LINK_TEXT = "copy";
128
129    /**
130     * New Document not submitted successfully
131     */
132    public static final String CREATE_NEW_DOCUMENT_NOT_SUBMITTED_SUCCESSFULLY_MESSAGE_TEXT = "New Document not submitted successfully";
133
134    /**
135     * //img[@alt='create new']
136     */
137    public static final String CREATE_NEW_XPATH = "//img[@alt='create new']";
138
139    /**
140     * //a[@title='Create a new record']
141     */
142    public static final String CREATE_NEW_XPATH2 = "//a[@title='Create a new record']";
143
144    /**
145     * div.dataTables_wrapper thead th
146     */
147    public static final String DATA_TABLE_TR_CSS = "div.dataTables_wrapper tbody tr";
148
149    /**
150     * //div[@class='error']"
151     */
152    public static final String DIV_ERROR_LOCATOR = "//div[@class='error']";
153
154    /**
155     * //div[@class='error']"
156     */
157    public static final String DIV_ERROR_LOCATOR_KRAD = "//div[@class='alert alert-danger']/ul";
158
159    /**
160     * //div[@class='msg-excol']
161     */
162    public static final String DIV_EXCOL_LOCATOR = "//div[@class='msg-excol']";
163
164    /**
165     * //div[@class='left-errmsg-tab']/div/div
166     */
167    public static final String DIV_LEFT_ERRMSG = "//div[@class='left-errmsg-tab']/div/div";
168
169    /**
170     * //input[@id='document.newMaintainableObject.code']
171     */
172    public static final String DOC_CODE_XPATH = "//input[@id='document.newMaintainableObject.code']";
173
174    /**
175     * //div[@id='headerarea']/div/table/tbody/tr[1]/td[1]
176     */
177    public static final String DOC_ID_XPATH = "//div[@id='headerarea']/div/table/tbody/tr[1]/td[1]";
178
179    /**
180     * //div[@id='headerarea']/div/table/tbody/tr[1]/td[1]
181     */
182    public static final String DOC_ID_KRAD_XPATH = "//div[@data-label=\"Document Number\"]";
183    /**
184     * //table[@id='row']/tbody/tr[1]/td[1
185     */
186    public static final String DOC_ID_XPATH_2 = "//table[@id='row']/tbody/tr[1]/td[1]";
187
188    /**
189     * //table[@id='row']/tbody/tr[1]/td[1]/a
190     */
191    public static final String DOC_ID_XPATH_3 ="//table[@id='row']/tbody/tr[1]/td[1]/a";
192
193    /**
194     * //input[@id='document.documentHeader.documentDescription']
195     */
196    public static final String DOC_DESCRIPTION_XPATH ="//input[@id='document.documentHeader.documentDescription']";
197
198    /**
199     * //div[@id='headerarea']/div/table/tbody/tr[1]/td[1]
200     */
201    public static final String DOC_INITIATOR_XPATH = "//div[@id='headerarea']/div/table/tbody/tr[2]/td[1]";
202
203    /**
204     * "//img[@alt='doc search']
205     */
206    public static final String DOC_SEARCH_XPATH = "//img[@alt='doc search']";
207
208    /**
209     * //a[@title='Document Search']
210     */
211    public static final String DOC_SEARCH_XPATH_TITLE = "//a[@title='Document Search']";
212
213    /**
214     * ENROUTE
215     */
216    public static final String DOC_STATUS_ENROUTE = "ENROUTE";
217
218    /**
219     * FINAL
220     */
221    public static final String DOC_STATUS_FINAL = "FINAL";
222
223    /**
224     * SAVED
225     */
226    public static final String DOC_STATUS_SAVED = "SAVED";
227
228    /**
229     * //table[@class='headerinfo']//tr[1]/td[2]
230     */
231    public static final String DOC_STATUS_XPATH = "//table[@class='headerinfo']//tr[1]/td[2]";
232
233    /**
234     * //table[@id='row']/tbody/tr[1]/td[4]
235     */
236    public static final String DOC_STATUS_XPATH_2 = "//table[@id='row']/tbody/tr[1]/td[4]";
237
238    /**
239     * //div[contains(div,'Document was successfully submitted.')]
240     */
241    public static final String DOC_SUBMIT_SUCCESS_MSG_XPATH ="//div[contains(div,'Document was successfully submitted.')]";
242
243    /**
244     * edit
245     */
246    public static final String EDIT_LINK_TEXT = "edit";
247
248    /**
249     * iframeportlet
250     */
251    public static final String IFRAMEPORTLET_NAME = "iframeportlet";
252
253    /**
254     * (//a[contains(text(),'Uif Components (Kitchen Sink)')])[2]
255     */
256    public static final String KITCHEN_SINK_XPATH = "(//a[contains(text(),'Uif Components (Kitchen Sink)')])";
257
258    /**
259     * KRAD
260     */
261    public static final String KRAD_XPATH = "KRAD";
262
263    /**
264     * Kuali :: Collection Totaling
265     */
266    public static final String KUALI_COLLECTION_TOTALLING_WINDOW_XPATH = "Kuali :: Collection Totaling";
267
268    /**
269     * //a[text()='Collection Totaling']
270     */
271    public static final String KUALI_COLLECTION_TOTALLING_XPATH = "//a[text()='Collection Totaling']";
272
273    /**
274     * Kuali :: Uif Components
275     */
276    public static final String KUALI_UIF_COMPONENTS_WINDOW_XPATH = "Kuali :: Uif Components";
277
278    /**
279     * "Kuali :: View Title"
280     */
281    public static final String KUALI_VIEW_WINDOW_TITLE = "Kuali :: View Title";
282
283    /**
284     * KUALI - Kuali Systems
285     */
286    public static final String LABEL_KUALI_KUALI_SYSTEMS = "KUALI - Kuali Systems";
287
288    /**
289     * KUALI : Default
290     */
291    public static final String LABEL_KUALI_DEFAULT = "KUALI : Default";
292
293    /**
294     * //input[@name='imageField' and @value='Logout']
295     */
296    public static final String LOGOUT_XPATH = "//input[@name='imageField' and @value='Logout']";
297
298    /**
299     * Main Menu
300     */
301    public static final String MAIN_MENU_LINK_TEXT = "Main Menu";
302
303    /**
304     * Kuali :: Rich Messages
305     */
306    public static final String RICH_MESSAGES_WINDOW_TITLE = "Kuali :: Rich Messages";
307
308    /**
309     * //div[contains(div,'Document was successfully saved.')]
310     */
311    public static final String SAVE_SUCCESSFUL_XPATH = "//div[contains(div,'Document was successfully saved.')]";
312
313    /**
314     * //input[@name='methodToCall.save' and @alt='save']
315     */
316    public static final String SAVE_XPATH="//input[@name='methodToCall.save' and @alt='save']";
317
318    /**
319     * KIM Screens
320     * //*[@name='methodToCall.save' and @alt='save']
321     */
322    public static final String SAVE_XPATH_2 = "//*[@name='methodToCall.save' and @alt='save']";
323
324    /**
325     * KIM Screens
326     * //*[@name='methodToCall.reload' and @alt='reload']
327     */
328    public static final String RELOAD_XPATH = "//*[@name='methodToCall.reload' and @alt='reload']";
329
330    /**
331     * //input[@title='search' and @name='methodToCall.search']
332     */
333    public static final String SAVE_XPATH_3 = "//input[@title='search' and @name='methodToCall.search']";
334
335    /**
336     * Search
337     */
338    public static final String SEARCH = "Search";
339
340    /**
341     * //input[@name='methodToCall.search' and @value='search']
342     */
343    public static final String SEARCH_XPATH="//input[@name='methodToCall.search' and @value='search']";
344
345    /**
346     * //input[@value='search']
347     */
348    public static final String SEARCH_XPATH_2 = "//input[@value='search']";
349
350    /**
351     * (//input[@name='methodToCall.search'])[2]
352     */
353    public static final String SEARCH_SECOND = "(//input[@name='methodToCall.search'])[2]";
354
355    /**
356     * //input[@name='methodToCall.route' and @alt='submit']
357     */
358    public static final String SUBMIT_XPATH="//input[@name='methodToCall.route' and @alt='submit']";
359
360    /**
361     * //input[@name='methodToCall.approve' and @alt='approve']
362     */
363    public static final String APPROVE_XPATH="//input[@name='methodToCall.approve' and @alt='approve']";
364
365    /**
366     * //input[@name='methodToCall.disapprove' and @alt='disapprove']
367     */
368    public static final String DISAPPROVE_XPATH="//input[@name='methodToCall.disapprove' and @alt='disapprove']";
369
370    /**
371     * //input[@name='methodToCall.acknowledge' and @alt='acknowledge']
372     */
373    public static final String ACKNOWLEDGE_XPATH="//input[@name='methodToCall.acknowledge' and @alt='acknowledge']";
374
375    /**
376     * //input[@name='methodToCall.close' and @alt='close']
377     */
378    public static final String CLOSE_XPATH="//input[@name='methodToCall.close' and @alt='close']";
379
380    /**
381     * Travel Account Lookup
382     */
383    public static final String TRAVEL_ACCOUNT_LOOKUP_LINK_TEXT = "Travel Account Lookup";
384
385    /**
386     * Uif Components (Kitchen Sink)
387     */
388    public static final String UIF_COMPONENTS_KITCHEN_SINK_LINK_TEXT = "Uif Components (Kitchen Sink)";
389
390    /**
391     * (//a[contains(text(),'Validation Framework Demo')])[2]
392     */
393    public static final String VALIDATION_FRAMEWORK_DEMO_XPATH = "(//a[contains(text(),'Validation Framework Demo')])";
394
395    /**
396     * XML Ingester
397     */
398    public static final String XML_INGESTER_LINK_TEXT = "XML Ingester";
399
400    /**
401     * //a[@title='FiscalOfficerInfo Maintenance (New)']
402     */
403    public static final String FISCAL_OFFICER_INFO_MAINTENANCE_NEW_XPATH = "//a[@title='FiscalOfficerInfo Maintenance (New)']";
404
405    static {
406        if (System.getProperty(WebDriverUtils.REMOTE_PROPERTIES_PROPERTY) != null) {
407            PropertiesUtils propUtils = new PropertiesUtils();
408            try {
409                propUtils.loadPropertiesWithSystemAndOverridesIntoSystem(System.getProperty(WebDriverUtils.REMOTE_PROPERTIES_PROPERTY));
410            } catch (IOException ioe) {
411                System.out.println("Exception opening " + System.getProperty(WebDriverUtils.REMOTE_PROPERTIES_PROPERTY) + " " + ioe.getMessage());
412            }
413        }
414    }
415
416    protected String namespaceCode = "KR-WKFLW";
417
418    protected String uiFramework = AutomatedFunctionalTestUtils.REMOTE_UIF_KNS;   // default to KNS
419
420    private static final Map<String, String> actionRequestLabelMap;
421    private static Map<String, String> actionRequestButtonMap;
422    static{
423        actionRequestLabelMap = new HashMap();
424        actionRequestLabelMap.put("A","APPROVE");
425        actionRequestLabelMap.put("F","FYI");
426        actionRequestLabelMap.put("C","COMPLETE");
427        actionRequestLabelMap.put("CR","COMPLETE");
428        actionRequestLabelMap.put("K","ACKNOWLEDGE");
429        actionRequestLabelMap.put("D","APPROVE");
430        actionRequestButtonMap = new HashMap();
431        actionRequestButtonMap.put("A","methodToCall.approve");
432        actionRequestButtonMap.put("F","methodToCall.fyi");
433        actionRequestButtonMap.put("C","methodToCall.complete");
434        actionRequestButtonMap.put("CR","methodToCall.route");
435        actionRequestButtonMap.put("K","methodToCall.acknowledge");
436        actionRequestButtonMap.put("D","methodToCall.disapprove");
437    }
438
439    /**
440     * 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.
441     * Setup the WebDriver properties, test, and login.  Named testSetUp so it runs after TestNG's startSession(Method)
442     * {@link WebDriverUtils#determineUser(String)}
443     * {@link WebDriverUtils#setUp(String, String, String, String)}
444     */
445    @Before
446    public void testSetUp() {
447        super.testSetUp();
448    }
449
450    /**
451     * // https://jira.kuali.org/browse/KULRICE-9804 KNS Create new link absent when Bookmark URL requires Login
452     * @return
453     */
454    @Override
455    protected String getTestUrl() {
456        String testUrl = super.getTestUrl();
457        if (testUrl.contains(AutomatedFunctionalTestUtils.HIDE_RETURN_LINK) &&
458                !testUrl.contains("&showMaintenanceLinks=true")) {
459            testUrl += "&showMaintenanceLinks=true";
460        }
461        return testUrl;
462    }
463
464
465    protected void impersonateUser(String user) throws InterruptedException {
466        waitAndTypeByName(BACKDOOR_ID_TEXT,user);
467        jGrowl("Click Backdoor Login");
468        waitAndClickByXpath(BACKDOOR_LOGIN_BUTTON_XPATH);
469    }
470
471    protected void addAdHocRecipientsGroup(String[] adHocRecipients) throws InterruptedException {
472        addAdHocRecipientsGroup(new String[][]{adHocRecipients});
473    }
474
475    protected void addAdHocRecipientsGroup(String[][] adHocRecipients) throws InterruptedException {
476        String today = getDateToday();
477        Calendar nextYearCal = Calendar.getInstance();
478        nextYearCal.add(Calendar.YEAR, 1);
479        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
480        String nextYear = sdf.format(nextYearCal.getTime());
481
482        waitAndClickByName("methodToCall.toggleTab.tabAdHocRecipients");
483        for (int i = 0, s = adHocRecipients.length; i < s; i++) {
484            selectOptionByName("newAdHocRouteWorkgroup.actionRequested", adHocRecipients[i][1]);
485            waitAndTypeByName("newAdHocRouteWorkgroup.recipientName", adHocRecipients[i][0]);
486            waitAndTypeByName("newAdHocRouteWorkgroup.recipientNamespaceCode", adHocRecipients[i][2]);
487            WebDriverUtils.jGrowl(getDriver(), "Click Add Group", false, "Click Add Group");
488            waitAndClickByName("methodToCall.insertAdHocRouteWorkgroup");
489        }
490    }
491
492    /**
493     * @param adHocRecipients user, action option value
494     * @throws InterruptedException
495     */
496    protected void addAdHocRecipientsPerson(String[] adHocRecipients) throws InterruptedException {
497        addAdHocRecipientsPerson(new String[][]{adHocRecipients});
498    }
499
500    /**
501     * @param adHocRecipients user, action option value
502     * @throws InterruptedException
503     */
504    protected void addAdHocRecipientsPerson(String[][] adHocRecipients) throws InterruptedException {
505        String today = getDateToday();
506        Calendar nextYearCal = Calendar.getInstance();
507        nextYearCal.add(Calendar.YEAR, 1);
508        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
509        String nextYear = sdf.format(nextYearCal.getTime());
510
511        if (!isVisible(By.name("newAdHocRoutePerson.actionRequested"))) {
512            waitAndClickByName("methodToCall.toggleTab.tabAdHocRecipients");
513        }
514        for (int i = 0, s = adHocRecipients.length; i < s; i++) {
515            selectOptionByName("newAdHocRoutePerson.actionRequested", adHocRecipients[i][1]);
516            waitAndTypeByName("newAdHocRoutePerson.id", adHocRecipients[i][0]);
517//            if (isElementPresentByName("member.activeFromDate")) {
518//                waitAndTypeByName("member.activeFromDate", today);
519//            }
520//            if (isElementPresentByName("member.activeFromDate")) {
521//                waitAndTypeByName("member.activeFromDate", nextYear);
522//            }
523            WebDriverUtils.jGrowl(getDriver(), "Click Add Person", false, "Click Add Person");
524            waitAndClickByName("methodToCall.insertAdHocRoutePerson");
525        }
526    }
527
528    protected void agendaLookupAssertions() throws Exception {
529        testLookUp();
530        assertTextPresent("Rules");
531        waitAndClickCancelByText();
532    }
533
534    protected void assertActionList(String docId, String actionListOptionValue, String state) throws InterruptedException {
535        selectTopFrame();
536        waitAndClickActionList();
537        selectFrameIframePortlet();
538        while (!waitForIsTextPresent(docId)) {
539            waitAndClickByLinkText("Next");
540        }
541        WebElement docIdTr = findElement(By.xpath("//table/tbody/tr/td/a[contains(text(), '" + docId + "')]/../.."));
542        assertTrue(docIdTr.getText() + " does not contain " + docId, docIdTr.getText().contains(docId));
543        assertTrue(docIdTr.getText() + " does not contain " + state, docIdTr.getText().contains(state));
544        assertTrue(docIdTr.getText() + " does not contain " + actionRequestLabelMap.get(actionListOptionValue), docIdTr.getText().contains(actionRequestLabelMap.get(actionListOptionValue)));
545//        assertTextPresent(new String[]{docId, actionRequestLabelMap.get(actionListOptionValue)});
546        waitAndClickLinkContainingText(docId);
547        selectChildWindow();
548        waitAndClickByName(actionRequestButtonMap.get(actionListOptionValue));
549
550        // Disapprove requires another step before checking outbox
551        if ("D".equals(actionListOptionValue)) {
552            waitAndTypeByName("reason","disapproved for AFT");
553            jGrowl("Click yes button");
554            waitAndClickByName("methodToCall.processAnswer.button0");
555        } else if ("C".equals(actionListOptionValue) || "CR".equals(actionListOptionValue)) {
556            waitAndClickByName("methodToCall.close");
557        }
558        waitForTextNotPresent(docId);
559    }
560
561    protected void assertNotInActionList(String docId) throws InterruptedException {
562        selectTopFrame();
563        waitAndClickActionList();
564        selectFrameIframePortlet();
565        waitForTextNotPresent(docId);
566        while (isElementPresentByLinkText("Next")) {
567            waitAndClickByLinkText("Next");
568            waitForTextNotPresent(docId);
569        }
570    }
571
572    protected void assertOutbox(String docId, String state) throws InterruptedException {
573        // find it in outbox
574        waitAndClickLinkContainingText("Outbox");
575        // TODO if the docId is present as part of uniqueString there will be a false negative it would be better if there
576        // was a waitForIsElementPresent
577        while (!waitForIsTextPresent(docId)) {
578            waitAndClickByLinkText("Next");
579        }
580        WebElement docIdTr = findElement(By.xpath("//table/tbody/tr/td/a[contains(text(), '" + docId + "')]/../.."));
581        assertTrue("Outbox items " + docIdTr.getText() + " does not contain " + docId, docIdTr.getText().contains(docId));
582        assertTrue("Outbox items " + docIdTr.getText() + " state is incorrect " + state, docIdTr.getText().contains(state));
583        waitForTextPresent(docId);
584
585//        // clear all items in the outbox
586//        waitAndClickAllByName("outboxItems");
587//        waitAndClickByName("methodToCall.removeOutboxItems");
588    }
589
590    protected void assertBlanketApproveButtonsPresent() {
591        assertElementPresentByName("methodToCall.route");
592        assertElementPresentByName("methodToCall.save");
593        assertElementPresentByName(BLANKET_APPROVE_NAME, "Blanket Approve button not present does " + user + " have permssion?");
594        assertElementPresentByName("methodToCall.close");
595        assertElementPresentByName(CANCEL_NAME);
596    }
597
598    protected void assertDocFinal(String docId) throws InterruptedException {
599        assertDocSearch(docId, DOC_STATUS_FINAL);
600    }
601
602    protected void assertDocSearch(String docId, String docStatus) throws InterruptedException {
603        docSearch(docId);
604        waitForElementPresentByXpath(DOC_ID_XPATH_3);
605        jGrowl("Is doc status for docId: " + docId + " " + docStatus + "?");
606        acceptAlertIfPresent(); // Agenda
607        assertEquals(docId, getTextByXpath(DOC_ID_XPATH_3));
608        assertEquals(docStatus, getTextByXpath(DOC_STATUS_XPATH_2));
609    }
610
611    protected void docSearch(String docId) throws InterruptedException {
612        selectParentWindow();
613        selectTopFrame();
614        waitAndClickDocSearchTitle();
615        acceptAlertIfPresent(); // Agenda
616        waitForPageToLoad();
617        selectFrameIframePortlet();
618        waitAndTypeByName("documentId", docId);
619        waitAndClickSearch();
620    }
621
622    protected void assertDocSearchNoResults(String docId) throws InterruptedException {
623        docSearch(docId);
624        waitForTextPresent("No values match this search.");
625    }
626
627    protected void assertRouteStatus(String status) throws InterruptedException {
628        waitForElementPresentByXpath("//th[contains(.,'Route Status')]/../following-sibling::*/td[contains(.,'" + status + "')]");
629    }
630
631    protected void assertTableLayout() throws Exception {
632        waitForTextPresent("Actions");
633        String pageSource = driver.getPageSource();
634        assertTrue(pageSource.contains("Table Layout"));
635        assertTrue(pageSource.contains("Field 1"));
636        assertTrue(pageSource.contains("Field 2"));
637        assertTrue(pageSource.contains("Field 3"));
638        assertTrue(pageSource.contains("Field 4"));
639        assertTrue(pageSource.contains("Actions"));
640    }
641
642    protected void blanketApproveAssert(String docId) throws InterruptedException {
643        checkForDocError();
644        assertDocSearch(docId, DOC_STATUS_FINAL);
645    }
646
647    protected void blanketApproveCheck() throws InterruptedException {
648        waitAndClickBlanketApproveKns();
649        checkForIncidentReport();
650    }
651
652    public static String blanketApprovalCleanUpErrorText(String errorText) {
653        errorText = errorText.replace("* required field", "").replace("\n", " ").trim(); // bit of extra ui text we don't care about
654        return errorText;
655    }
656
657    /**
658     * Tests blanket approve action.
659     * This method is used by several different tests which perform various types of blanket approvals.
660     * Therefore, this is a candidate to remain in this base class
661     *
662     * @throws InterruptedException
663     */
664    protected void blanketApproveTest(String docId) throws InterruptedException {
665        jGrowl("Click Blanket Approve");
666        waitAndClickBlanketApproveKns();
667        Thread.sleep(2000);
668        checkForIncidentReport();
669        blanketApproveAssert(docId);
670    }
671
672    protected void blanketApproveSuccessfully() throws InterruptedException {
673        waitAndClickBlanketApprove();
674        waitAndClickConfirmBlanketApproveOk();
675        acceptAlertIfPresent(); // LabsLookupDefaultCreateNewBlanketApproveAft
676        waitForProgressLoading();
677        checkForDocErrorKrad();
678        waitForTextPresent("Document was successfully approved.");
679    }
680
681    protected void failOnErrorMessageItem() {
682        failOnErrorMessageItem(this.getClass().getName());
683    }
684
685    protected void failOnErrorMessageItem(String message) {
686        final String error_locator = "//li[@class='uif-errorMessageItem']";
687        if (findElements(By.xpath(error_locator)).size() > 0) {
688            String errorText = null;
689
690            try {
691                errorText = getTextByXpath(error_locator);
692            } catch (InterruptedException e) {
693                e.printStackTrace();
694            }
695
696            if (errorText != null && errorText.contains("errors")) {
697                jiraAwareFail((errorText + " " + message).trim());
698            }
699
700        }
701    }
702
703    /**
704     * Uses Selenium's findElements method which does not throw a test exception if not found.
705     */
706    public void checkForDocError() {
707        if (hasDocError()) {
708            String errorText = extractErrorText();
709            jiraAwareFail(errorText);
710        }
711    }
712
713    /**
714     * Uses Selenium's findElements method which does not throw a test exception if not found.
715     */
716    public void checkForDocErrorKrad() {
717        if (hasDocErrorKrad()) {
718            String errorText = extractErrorTextKrad();
719            jiraAwareFail(errorText);
720        }
721    }
722
723    protected String extractErrorText() {
724        String errorText = driver.findElement(By.xpath(DIV_ERROR_LOCATOR)).getText(); // don't highlight
725        errorText = blanketApprovalCleanUpErrorText(errorText);
726        if (driver.findElements(By.xpath(DIV_EXCOL_LOCATOR)).size() > 0) { // not present if errors are at the bottom of the page (see left-errmsg below)
727            errorText = blanketApprovalCleanUpErrorText(driver.findElement(
728                    // don't highlight
729                    By.xpath(DIV_EXCOL_LOCATOR)).getText()); // replacing errorText as DIV_EXCOL_LOCATOR includes the error count
730        }
731        if (driver.findElements(By.xpath(DIV_LEFT_ERRMSG)).size() > 0) {
732            errorText = errorText + blanketApprovalCleanUpErrorText(driver.findElement(
733                    By.xpath(DIV_LEFT_ERRMSG)).getText()); // don't highlight
734        }
735        return errorText;
736    }
737
738    protected String extractErrorTextKrad() {
739        return driver.findElement(By.xpath(DIV_ERROR_LOCATOR_KRAD)).getText(); // don't highlight
740    }
741
742    /**
743     * Uses Selenium's findElements method which does not throw a test exception if not found.
744     * @return
745     */
746    public boolean hasDocError() {
747        acceptAlertIfPresent(); // Agenda
748        if (driver.findElements(By.xpath(DIV_ERROR_LOCATOR)).size() > 0) {
749            String errorText = driver.findElement(By.xpath(DIV_ERROR_LOCATOR)).getText(); // don't highlight
750            if (errorText != null && errorText.contains("error(s) found on page.")) {
751                return true;
752            }
753        }
754        return false;
755    }
756
757    /**
758     * Uses Selenium's findElements method which does not throw a test exception if not found.
759     * @return
760     */
761    public boolean hasDocErrorKrad() {
762        if (driver.findElements(By.xpath(DIV_ERROR_LOCATOR_KRAD)).size() > 0) {
763            String errorText = driver.findElement(By.xpath(DIV_ERROR_LOCATOR_KRAD)).getText(); // don't highlight
764            if (errorText != null && !errorText.equals("")) {
765                return true;
766            }
767        }
768        return false;
769    }
770
771    /**
772     * Uses Selenium's findElements method which does not throw a test exception if not found.
773     * @param errorTextToMatch
774     * @return
775     */
776    public boolean hasDocError(String errorTextToMatch) {
777        if (driver.findElements(By.xpath(DIV_ERROR_LOCATOR)).size() > 0) {
778            String errorText = driver.findElement(By.xpath(DIV_ERROR_LOCATOR)).getText(); // don't highlight
779            if (errorText != null && errorText.contains("error(s) found on page.")) {
780                WebElement errorDiv = driver.findElement(By.xpath("//div[@class='left-errmsg']/div[2]/div")); // don't highlight
781                if (errorDiv != null) {
782                    errorText = errorDiv.getText();
783                    return errorText != null && errorText.contains(errorTextToMatch);
784                }
785            }
786        }
787        return false;
788    }
789
790    protected String configNameSpaceBlanketApprove() throws Exception {
791        String docId = waitForDocId();
792        String dtsPlusTwoChars = AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
793        waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Validation Test Namespace " + AutomatedFunctionalTestUtils
794                .createUniqueDtsPlusTwoRandomCharsNot9Digits());
795        assertBlanketApproveButtonsPresent();
796        waitAndTypeByXpath(DOC_CODE_XPATH, "VTN" + dtsPlusTwoChars);
797        waitAndTypeByXpath("//input[@id='document.newMaintainableObject.name']",
798                "Validation Test NameSpace " + dtsPlusTwoChars);
799        waitAndTypeByXpath("//input[@id='document.newMaintainableObject.applicationId']", "RICE");
800
801        return docId;
802    }
803
804    protected void contextLookupAssertions() throws Exception {
805        testLookUp();
806        assertTextPresent("Notes and Attachments");
807        jGrowl("Click Cancel");
808        waitAndClickByXpath("//button[@data-performDirtyValidation=\"true\"]"); // first cancel button is for attachment cancel and is hidden
809    }
810
811    //    protected void deleteSubCollectionLine() throws Exception {
812    //        // click on collections page link
813    //        waitAndClickByLinkText(COLLECTIONS_LINK_TEXT);
814    //        Thread.sleep(5000);
815    //
816    //        // wait for collections page to load by checking the presence of a sub collection line item
817    //        waitForElementPresentByName("list4[0].subList[0].field1");
818    //
819    //        // change a value in the line to be deleted
820    //        waitAndTypeByName("list4[0].subList[0].field1", "selenium");
821    //
822    //        // click the delete button
823    //        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");
824    //        Thread.sleep(2000);
825    //
826    //        // confirm that the input box containing the modified value is not present
827    //        for (int second = 0;; second++) {
828    //            if (second >= waitSeconds)
829    //                jiraAwareFail(TIMEOUT_MESSAGE);
830    //            try {
831    //                if (!"selenium".equals(waitAndGetAttributeByName("list4[0].subList[0].field1", "value")))
832    //                    break;
833    //            } catch (Exception e) {}
834    //            Thread.sleep(1000);
835    //        }
836    //
837    //        // verify that the value has changed for the input box in the line that has replaced the deleted one
838    //        assertNotSame("selenium", waitAndGetAttributeByName("list4[0].subList[0].field1", "value"));
839    //    }
840
841    protected void expandColapseByXpath(String clickLocator, String visibleLocator) throws InterruptedException {
842        waitAndClickByXpath(clickLocator);
843        waitIsVisibleByXpath(visibleLocator);
844        waitAndClickByXpath(clickLocator);
845        waitNotVisibleByXpath(visibleLocator);
846    }
847
848    protected String getDocStatus() {
849        return findElement(By.xpath(DOC_STATUS_XPATH_2)).getText();
850    }
851
852    /**
853     * <p>
854     * Handles simple nested frame content; validates that a frame and nested frame exists before
855     * switching to it.
856     * </p><p>
857     * Uses Selenium's findElements method which does not throw a test exception if not found.
858     * </p>
859     */
860    protected void gotoNestedFrame() {
861        driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
862        driver.switchTo().defaultContent();
863        final String iframeXpath = "//iframe";
864
865        gotoIframeByXpath(iframeXpath);
866
867        gotoIframeByXpath(iframeXpath);
868
869        driver.manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
870    }
871
872    @Override
873    protected void logout() throws InterruptedException {
874        selectTopFrame();
875        if (isElementPresentByXpath(LOGOUT_XPATH)) {
876            waitAndClickLogout(this);
877        }
878    }
879
880    protected void lookupDocByWildcardedUniqueStringName() throws InterruptedException {
881        open(getBaseUrlString() + getBookmarkUrl());
882        selectFrameIframePortlet();
883        waitAndTypeByName("name", "*" + uniqueString);
884        waitAndClickSearch();
885    }
886
887    protected boolean noAffilication() {
888        return !isElementPresentByName("document.affiliations[0].dflt");
889    }
890
891    /**
892     * recalls a document.
893     * closes the page when done.
894     *
895     * @param cancel if true, performs recall and cancel. if false, performs recall to action list
896     *
897     * @throws InterruptedException
898     */
899    protected void recall(boolean cancel) throws InterruptedException {
900        waitAndClickByName("methodToCall.recall");
901        waitForTextPresent("the reason below");
902        waitAndTypeByName("reason", "Recall " + uniqueString);
903        if (cancel){
904            // recall and cancel
905            waitAndClickByName("methodToCall.processAnswer.button1");
906            waitForTextPresent("RECALLED");
907            waitAndClickByName("methodToCall.close");
908        } else {
909            // recall to action list
910            waitAndClickByName("methodToCall.processAnswer.button0");
911            waitForTextPresent("SAVED");
912            waitAndClickByName("methodToCall.close");
913            waitAndClickByName("methodToCall.processAnswer.button1");
914        }
915    }
916
917    protected void saveSuccessfully() throws InterruptedException {
918        saveSuccessfully(WebDriverUtils.configuredImplicityWait() * 4);
919    }
920
921    protected void saveSuccessfully(int secondsToWait) throws InterruptedException {
922        waitAndClickSaveByText();
923        waitForProgressSaving(secondsToWait);
924        checkForDocErrorKrad();
925        waitForTextPresent("Document was successfully saved.");
926    }
927
928    protected void selectFrameIframePortlet() {
929        selectFrame(IFRAMEPORTLET_NAME);
930    }
931
932    protected void selectFrame(String locator) {
933
934        if (IFRAMEPORTLET_NAME.equals(locator)) {
935            gotoNestedFrame();
936        } else {
937            WebDriverUtils.selectFrameSafe(driver, locator);
938        }
939    }
940
941    protected void submitSuccessfully() throws InterruptedException {
942        submitSuccessfully(WebDriverUtils.configuredImplicityWait() * 4);
943    }
944
945    protected void submitSuccessfully(int loadingSeconds) throws InterruptedException {
946        waitAndClickSubmitByText();
947        waitAndClickConfirmSubmitOk();
948        waitForProgressLoading(loadingSeconds);
949        Thread.sleep(500);
950        checkForDocError();
951        checkForDocErrorKrad();
952        waitForTextPresent("Document was successfully submitted.");
953    }
954
955    protected void testAddingBrownGroup() throws Exception {
956        selectFrameIframePortlet();
957        waitAndCreateNew();
958        String docId = waitForDocId();
959        String random = RandomStringUtils.randomNumeric(4);
960        String organizationDocumentNumber = "ORD" + random;
961        String groupDescription = "GD" + random;
962        String groupName = "BrownGroup " + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
963        String nameSpace = "KR-IDM";
964        String today = getDateToday();
965        Calendar nextYearCal = Calendar.getInstance();
966        nextYearCal.add(Calendar.YEAR, 1);
967        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
968        String nextYear = sdf.format(nextYearCal.getTime());
969
970        //Enter details for BrownGroup.
971        waitAndTypeByName("document.documentHeader.documentDescription", "Adding Brown Group");
972        waitAndTypeByName("document.documentHeader.explanation", "I want to add Brown Group to test KIM");
973        waitAndTypeByName("document.documentHeader.organizationDocumentNumber", organizationDocumentNumber);
974        selectOptionByName("document.groupNamespace", nameSpace);
975        waitAndTypeByName("document.groupName", groupName);
976        waitAndTypeByName("document.groupDescription", groupDescription);
977        
978        checkByName("document.active");
979        waitAndClickByXpath(SAVE_XPATH_2);
980        waitForTextPresent("Document was successfully saved.");
981    }
982    
983    protected void testAddingBrownGroupSubmit() throws Exception {
984        selectFrameIframePortlet();
985        waitAndCreateNew();
986        String docId = waitForDocId();
987        String random = RandomStringUtils.randomNumeric(4);
988        String organizationDocumentNumber = "ORD" + random;
989        String groupDescription = "GD" + random;
990        String groupName = "BrownGroup " + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
991        String nameSpace = "KR-IDM";
992        String today = getDateToday();
993        acceptAlertIfPresent();
994        Calendar nextYearCal = Calendar.getInstance();
995        nextYearCal.add(Calendar.YEAR, 1);
996        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
997        String nextYear = sdf.format(nextYearCal.getTime());
998
999        //Enter details for BrownGroup.
1000        waitAndTypeByName("document.documentHeader.documentDescription", "Adding Brown Group");
1001        waitAndTypeByName("document.documentHeader.explanation", "I want to add Brown Group to test KIM");
1002        waitAndTypeByName("document.documentHeader.organizationDocumentNumber", organizationDocumentNumber);
1003        selectOptionByName("document.groupNamespace", nameSpace);
1004        waitAndTypeByName("document.groupName", groupName);
1005        waitAndTypeByName("document.groupDescription", groupDescription);
1006
1007        checkByName("document.active");
1008        waitAndClickByXpath(SUBMIT_XPATH);
1009    }
1010    
1011    protected void testAddingBrownGroupSaveSubmit() throws Exception {
1012        selectFrameIframePortlet();
1013        waitAndCreateNew();
1014        String docId = waitForDocId();
1015        String random = RandomStringUtils.randomNumeric(4);
1016        String organizationDocumentNumber = "ORD" + random;
1017        String groupDescription = "GD" + random;
1018        String groupName = "BrownGroup " + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
1019        String nameSpace = "KR-IDM";
1020        String today = getDateToday();
1021        Calendar nextYearCal = Calendar.getInstance();
1022        nextYearCal.add(Calendar.YEAR, 1);
1023        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
1024        String nextYear = sdf.format(nextYearCal.getTime());
1025
1026        //Enter details for BrownGroup.
1027        waitAndTypeByName("document.documentHeader.documentDescription", "Adding Brown Group");
1028        waitAndTypeByName("document.documentHeader.explanation", "I want to add Brown Group to test KIM");
1029        waitAndTypeByName("document.documentHeader.organizationDocumentNumber", organizationDocumentNumber);
1030        selectOptionByName("document.groupNamespace", nameSpace);
1031        waitAndTypeByName("document.groupName", groupName);
1032        waitAndTypeByName("document.groupDescription", groupDescription);
1033
1034        waitAndClickByXpath(SAVE_XPATH_2);
1035        waitForTextPresent("Document was successfully saved.");
1036        waitAndClickByXpath(SUBMIT_XPATH);
1037        waitForTextPresent("Document was successfully submitted.");
1038    }
1039
1040    protected void testAttributeDefinitionLookUp() throws Exception {
1041        waitForPageToLoad();
1042        selectFrameIframePortlet();
1043        waitAndClickByXpath("//button[contains(.,'earch')]");
1044        Thread.sleep(3000);
1045        waitForPageToLoad();
1046        findElement(By.tagName("body")).getText().contains("Actions"); // there are no actions, but the header is the only unique text from searching
1047        waitAndClickByLinkText("1000");
1048        waitForPageToLoad();
1049        findElement(By.tagName("body")).getText().contains("Attribute Inquiry");
1050        findElement(By.tagName("body")).getText().contains("KRMS Attributes");
1051        findElement(By.tagName("body")).getText().contains("Attribute Label");
1052        findElement(By.tagName("body")).getText().contains("1000");
1053        findElement(By.tagName("body")).getText().contains("peopleFlowId");
1054        findElement(By.tagName("body")).getText().contains("KR-RULE");
1055        findElement(By.tagName("body")).getText().contains("PeopleFlow");
1056
1057        // selectFrame("name=fancybox-frame1343151577256"); // TODO parse source to get name
1058        // jiraAwareWaitAndClick("css=button:contains(Close)"); // looks lower case, but is upper
1059        // Thread.sleep(500);
1060        // jiraAwareWaitAndClick("css=button:contains(cancel)");
1061        // AttributeDefinition's don't have actions (yet)
1062        // jiraAwareWaitAndClick("id=u80");
1063        // waitForPageToLoad();
1064        // jiraAwareWaitAndClick("id=u86");
1065        // waitForPageToLoad();
1066        // selectWindow("null");
1067        // jiraAwareWaitAndClick("xpath=(//input[@name='imageField'])[2]");
1068        // waitForPageToLoad();
1069        passed();
1070    }
1071
1072    protected String testBlanketApprove() throws Exception {
1073        selectFrameIframePortlet();
1074        waitAndCreateNew();
1075        String docId = verifyDocInitiated();
1076        assertBlanketApproveButtonsPresent();
1077        createNewLookupDetails();
1078
1079        jGrowl("Click Blanket Approve");
1080        waitAndClickBlanketApproveKns();
1081
1082        int attempts = 0;
1083        while (hasDocError() && extractErrorText().contains("a record with the same primary key already exists.") &&
1084                ++attempts <= 3) {
1085            uniqueString = null; // make sure try a new one
1086            jGrowl("record with the same primary key already exists");
1087            createNewEnterDetails();
1088            jGrowl("Click Blanket Approve");
1089            waitAndClickBlanketApproveKns();
1090        }
1091
1092        checkForIncidentReport();
1093        blanketApproveAssert(docId);
1094        return docId;
1095    }
1096
1097    protected void waitAndClickBlanketApproveKns() throws InterruptedException {
1098        waitAndClickByName(BLANKET_APPROVE_NAME,
1099                "No blanket approve button does the user " + getUserName() + " have permission?");
1100        waitForProgressLoading();
1101    }
1102
1103    protected void testCancelConfirmation() throws InterruptedException {
1104        waitAndCancelConfirmation();
1105    }
1106
1107    protected void testCreateDocType() throws Exception {
1108        selectFrameIframePortlet();
1109        waitAndCreateNew();
1110        assertElementPresentByXpath("//*[@name='methodToCall.route' and @alt='submit']","submit button does not exist on the page");
1111
1112        //waitForElementPresentByXpath(DOC_ID_XPATH);
1113        //String docId = findElement(By.xpath(DOC_ID_XPATH)).getText();
1114        String docId = waitForDocId();
1115        waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Creating new Document Type");
1116        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,`)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;"
1117                + getBaseUrlString() + "/kr/lookup.do;::::).anchor4']";
1118        waitAndClickByXpath(parentDocType);
1119        waitForPageToLoad();
1120        Thread.sleep(2000);
1121        waitAndClickSearch();
1122        waitAndClickReturnValue();
1123        String docTypeName = "TestDocType" + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
1124        waitForElementPresentByXpath("//input[@id='document.newMaintainableObject.name']");
1125        waitAndTypeByXpath("//input[@id='document.newMaintainableObject.name']", docTypeName);
1126        waitAndTypeByXpath("//input[@id='document.newMaintainableObject.unresolvedDocHandlerUrl']","${kr.url}/maintenance.do?methodToCall=docHandler");
1127
1128        //waitAndTypeByXpath("//input[@id='document.newMaintainableObject.actualNotificationFromAddress']", "NFA");
1129        waitAndTypeByXpath("//input[@id='document.newMaintainableObject.label']", "Label for " + docTypeName);
1130        waitAndTypeByXpath("//input[@id='document.newMaintainableObject.unresolvedHelpDefinitionUrl']","default.htm?turl=WordDocuments%2Fdocumenttype.htm");
1131        jGrowl("Click Submit button");
1132        waitAndClickByXpath("//*[@name='methodToCall.route' and @alt='submit']");
1133        checkForIncidentReport();
1134        waitForPageToLoad();
1135        driver.switchTo().defaultContent();
1136        waitAndClickDocSearchTitle();
1137        waitForPageToLoad();
1138        selectFrameIframePortlet();
1139        waitAndTypeByName("documentId", docId);
1140        waitAndClickSearch();
1141        assertEquals(docId, waitForElementPresent(By.xpath(DOC_ID_XPATH_2)).getText());
1142    }
1143
1144    protected String testCreateNew() throws InterruptedException {
1145        selectFrameIframePortlet();
1146        waitAndCreateNew();
1147        String docId = verifyDocInitiated();
1148        createNewEnterDetails();
1149        return docId;
1150    }
1151
1152    protected String testCreateNewCancel() throws Exception {
1153        selectFrameIframePortlet();
1154        waitAndCreateNew();
1155        String docId = verifyDocInitiated();
1156        createNewEnterDetails();
1157        testCancelConfirmation();
1158        assertDocSearchNoResults(docId);
1159        return docId;
1160    }
1161
1162    protected void testCreateNewRequired() throws Exception {
1163        selectFrameIframePortlet();
1164        waitAndCreateNew();
1165        waitAndClickSubmit();
1166        assertTrue(waitForElementVisibleBy(By.xpath("//div[@class='error']")).getText().contains(
1167                " error(s) found on page."));
1168    }
1169    
1170    protected String testCreateNewSave() throws Exception {
1171        selectFrameIframePortlet();
1172        waitAndCreateNew();
1173        String docId = verifyDocInitiated();
1174        createNewEnterDetails();
1175        waitAndClickSave();
1176
1177        int attempts = 0;
1178        while (hasDocError() && extractErrorText().contains("a record with the same primary key already exists.") &&
1179                ++attempts <= 3) {
1180            uniqueString = null; // make sure try a new one
1181            jGrowl("record with the same primary key already exists");
1182            createNewEnterDetails();
1183            waitAndClickSave();
1184        }
1185
1186        checkForDocError();
1187        waitForSuccessfulSaveMessage();
1188        assertDocSearch(docId, "SAVED");
1189        waitAndClickRouteLogIcon();
1190        assertRouteStatus("SAVED");
1191        back();
1192        return docId;
1193    }
1194
1195    protected void waitForSuccessfulSaveMessage() throws InterruptedException {
1196        waitForElementVisibleBy(By.xpath(SAVE_SUCCESSFUL_XPATH));
1197    }
1198
1199    protected String testCreateNewSubmit() throws Exception {
1200        selectFrameIframePortlet();
1201        waitAndCreateNew();
1202        String docId = verifyDocInitiated();
1203        createNewEnterDetails();
1204        waitAndClickSubmit();
1205        int attempts = 0;
1206        while (hasDocError() && extractErrorText().contains("a record with the same primary key already exists.") &&
1207                ++attempts <= 3) {
1208            uniqueString = null; // make sure try a new one
1209            jGrowl("record with the same primary key already exists");
1210            createNewEnterDetails();
1211            waitAndClickSubmit();
1212        }
1213
1214        checkForDocError();
1215        waitForSuccessfulSubmitMessage();
1216        assertDocSearch(docId, "FINAL");
1217        waitAndClickRouteLogIcon();
1218        assertRouteStatus("FINAL");
1219        back();
1220        return docId;
1221    }
1222
1223    protected void waitForSuccessfulSubmitMessage()
1224            throws InterruptedException {waitForElementVisibleBy(By.xpath(DOC_SUBMIT_SUCCESS_MSG_XPATH));}
1225
1226    protected String testCreateNewSaveSubmit() throws Exception {
1227        selectFrameIframePortlet();
1228        waitAndCreateNew();
1229        String docId = verifyDocInitiated();
1230        createNewEnterDetails();
1231        waitAndClickSave();
1232
1233        int attempts = 0;
1234        while (hasDocError() && extractErrorText().contains("a record with the same primary key already exists.") &&
1235                ++attempts <= 3) {
1236            uniqueString = null; // make sure try a new one
1237            jGrowl("record with the same primary key already exists");
1238            createNewEnterDetails();
1239            waitAndClickSave();
1240        }
1241
1242        checkForDocError();
1243        waitForSuccessfulSaveMessage();
1244        waitAndClickSubmit();
1245        checkForDocError();
1246        waitForSuccessfulSubmitMessage();
1247        assertDocSearch(docId, "FINAL");
1248        waitAndClickRouteLogIcon();
1249        assertRouteStatus("FINAL");
1250        back();
1251        return docId;
1252    }
1253
1254    protected String verifyDocInitiated() throws InterruptedException {
1255        String docId = waitForDocId();
1256        assertEquals("INITIATED", waitForDocStatus());
1257        assertEquals(getUserName(), waitForDocInitiator());
1258        return docId;
1259    }
1260
1261    protected List<String> testCreateNewParameter(String docId, String parameterName) throws Exception {
1262        waitForPageToLoad();
1263        docId = waitForDocId();
1264        //Enter details for Parameter.
1265        waitAndTypeByName("document.documentHeader.documentDescription", "Adding Test Parameter");
1266        selectOptionByName("document.newMaintainableObject.namespaceCode", "KR-WKFLW");
1267        waitAndTypeByName("document.newMaintainableObject.componentCode", "ActionList");
1268        waitAndTypeByName("document.newMaintainableObject.applicationId", "KUALI");
1269        parameterName = "TestIndicator" + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
1270        waitAndTypeByName("document.newMaintainableObject.name", parameterName);
1271        waitAndTypeByName("document.newMaintainableObject.value", "Y");
1272        waitAndTypeByName("document.newMaintainableObject.description", "for testing");
1273        selectOptionByName("document.newMaintainableObject.parameterTypeCode", "HELP");
1274        waitAndClickByXpath("//input[@name='document.newMaintainableObject.evaluationOperatorCode' and @value='A']");
1275        waitAndClickSave();
1276        waitAndClickSubmit();
1277        waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
1278
1279
1280        assertDocSearch(docId, DOC_STATUS_FINAL);
1281        selectTopFrame();
1282        List<String> params = new ArrayList<String>();
1283        params.add(docId);
1284        params.add(parameterName);
1285
1286        return params;
1287    }
1288
1289    protected List<String> testCreateNewParameterType(String docId, String parameterType, String parameterCode)throws Exception {
1290        waitForPageToLoad();
1291        docId = waitForDocId();
1292
1293        //Enter details for Parameter.
1294        waitAndTypeByName("document.documentHeader.documentDescription", "Adding Test Parameter Type");
1295        parameterCode = RandomStringUtils.randomAlphabetic(4).toLowerCase();
1296        waitAndTypeByName("document.newMaintainableObject.code", parameterCode);
1297        parameterType = "testing " + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
1298        waitAndTypeByName("document.newMaintainableObject.name", parameterType);
1299        waitAndClickSave();
1300        waitAndClickSubmit();
1301        waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
1302        assertDocSearch(docId, DOC_STATUS_FINAL);
1303        selectTopFrame();
1304        List<String> params = new ArrayList<String>();
1305        params.add(docId);
1306        params.add(parameterType);
1307        params.add(parameterCode);
1308
1309        return params;
1310    }
1311
1312    protected void testCreateNewSearchReturnValueCancelConfirmation() throws InterruptedException, Exception {
1313        selectFrameIframePortlet();
1314        waitAndCreateNew();
1315        waitAndClickSearch2();
1316        waitAndClickReturnValue();
1317        waitAndCancelConfirmation();
1318        passed();
1319    }
1320
1321    protected List<String> testCopyParameter(String docId, String parameterName) throws Exception {
1322        selectFrameIframePortlet();
1323        waitAndClickCopy();
1324        waitForPageToLoad();
1325        docId = waitForDocId();
1326        waitAndTypeByName("document.documentHeader.documentDescription", "Copying Test Parameter");
1327        selectOptionByName("document.newMaintainableObject.namespaceCode", "KR-WKFLW");
1328        waitAndTypeByName("document.newMaintainableObject.componentCode", "ActionList");
1329        waitAndTypeByName("document.newMaintainableObject.applicationId", "KUALI");
1330        parameterName = "TestIndicator" + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
1331        waitAndTypeByName("document.newMaintainableObject.name", parameterName);
1332        waitAndClickSave();
1333        waitAndClickSubmit();
1334        waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
1335        assertDocSearch(docId, DOC_STATUS_FINAL);
1336        selectTopFrame();
1337        List<String> params = new ArrayList<String>();
1338        params.add(docId);
1339        params.add(parameterName);
1340
1341        return params;
1342    }
1343
1344    protected List<String> testCopyParameterType(String docId, String parameterType, String parameterCode) throws Exception {
1345        selectFrameIframePortlet();
1346        waitAndClickCopy();
1347        waitForPageToLoad();
1348        docId = waitForDocId();
1349        waitAndTypeByName("document.documentHeader.documentDescription", "Copying Test Parameter");
1350        parameterCode = RandomStringUtils.randomAlphabetic(4).toLowerCase();
1351        waitAndTypeByName("document.newMaintainableObject.code", parameterCode);
1352        clearTextByName("document.newMaintainableObject.name");
1353        parameterType = "testing " + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
1354        waitAndTypeByName("document.newMaintainableObject.name", parameterType);
1355        waitAndClickSave();
1356        waitAndClickSubmit();
1357        waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
1358        assertDocSearch(docId, DOC_STATUS_FINAL);
1359        selectTopFrame();
1360        List<String> params = new ArrayList<String>();
1361        params.add(docId);
1362        params.add(parameterType);
1363        params.add(parameterCode);
1364
1365        return params;
1366    }
1367
1368    protected void testDemoCustomRuleEventAndDocumentEventMethodInvocationAccountTypeChec() throws InterruptedException {
1369        String randomCode = org.apache.commons.lang3.RandomStringUtils.randomAlphabetic(9).toUpperCase();
1370        waitAndTypeByName("document.documentHeader.documentDescription","Travel Account Maintenance New Test Document " + randomCode);
1371        waitAndTypeByName("document.newMaintainableObject.dataObject.number",randomCode);
1372        waitAndTypeByName("document.newMaintainableObject.dataObject.name","Test Account Name " + randomCode);
1373        waitAndClickByXpath("//button[contains(text(),'Submit')]");
1374        assertTravelAccountTypeCodeRequired();
1375    }
1376
1377    protected void assertTravelAccountTypeCodeRequired() throws InterruptedException {
1378        waitForTextPresent("Travel Account Type Code: Required");
1379        fireEvent("document.newMaintainableObject.dataObject.accountTypeCode", "focus");
1380        waitForElementVisibleBy(By.xpath("//div[@class='popover top in uif-tooltip-error-cs']"));
1381        fireEvent("document.newMaintainableObject.dataObject.accountTypeCode", "blur");
1382        waitAndTypeByName("document.newMaintainableObject.dataObject.number", "a"); // focus, blur just doesn't do it sometimes
1383        if(isVisibleByXpath("//div[@class='popover top in uif-tooltip-error-cs']")){
1384            JiraAwareFailureUtils.fail("Required popup still present", this);
1385        }
1386    }
1387
1388    protected void testDocTypeLookup() throws Exception {
1389        selectFrameIframePortlet();
1390        waitAndClickByXpath("//input[@title='Search Parent Name']");
1391        waitAndClickByXpath(SAVE_XPATH_3);
1392        waitAndClickByXpath("//table[@id='row']/tbody/tr[contains(td[3],'RiceDocument')]/td[1]/a");
1393        waitAndClickByXpath(SAVE_XPATH_3);
1394        assertEquals("RiceDocument", getTextByXpath("//table[@id='row']/tbody/tr/td[4]/a"));
1395        waitAndClickByName("methodToCall.clearValues");
1396        waitAndTypeByName("name", "Kuali*D");
1397        waitAndClickByXpath(SAVE_XPATH_3);
1398        assertElementPresentByXpath("//table[@id='row']/tbody/tr[contains(td[3], 'KualiDocument')]");
1399        String docIdOld = getTextByXpath("//table[@id='row']/tbody/tr[contains(td[3], 'KualiDocument')]/td[2]/a");
1400        waitAndClickByName("methodToCall.clearValues");
1401        waitAndTypeByName("label", "KualiDocument");
1402        waitAndClickByXpath(SAVE_XPATH_3);
1403        assertElementPresentByXpath("//table[@id='row']/tbody/tr[contains(td[5], 'KualiDocument')]");
1404        waitAndClickByName("methodToCall.clearValues");
1405        waitAndTypeByName("documentTypeId", docIdOld);
1406        waitAndClickByXpath(SAVE_XPATH_3);
1407        assertElementPresentByXpath("//table[@id='row']/tbody/tr[contains(td[2], '" + docIdOld + "')]");
1408    }
1409
1410    protected void testEditCopy(String docId) throws InterruptedException {
1411        String desc = getDescriptionUnique();
1412        jiraAwareTypeByName("document.documentHeader.documentDescription", desc);
1413        String thisDocId = verifyDocInitiated();
1414        assertFalse("Document id should not be the same as original (" + docId + ").", docId.equals(thisDocId));
1415        waitAndClickSave();
1416        waitForSuccessfulSaveMessage();
1417        assertDocSearch(docId, "FINAL");
1418        waitAndClickRouteLogIcon();
1419        assertRouteStatus("FINAL");
1420        waitForElementPresentByXpath("//th[contains(.,'Title')]/../following-sibling::*/td[contains(.,'" + desc + "')]");
1421    }
1422
1423    protected List<String> testEditParameterType(String docId, String parameterType, String parameterCode) throws Exception {
1424        selectFrameIframePortlet();
1425        waitAndClickEdit();
1426        waitForPageToLoad();
1427        docId = waitForDocId();
1428        waitAndTypeByName("document.documentHeader.documentDescription", "Editing Test Parameter");
1429        clearTextByName("document.newMaintainableObject.name");
1430        parameterType = "testing " + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
1431        waitAndTypeByName("document.newMaintainableObject.name", parameterType);
1432        waitAndClickSave();
1433        waitAndClickSubmit();
1434        waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
1435        assertDocSearch(docId, DOC_STATUS_FINAL);
1436        selectTopFrame();
1437        List<String> params = new ArrayList<String>();
1438        params.add(docId);
1439        params.add(parameterType);
1440        params.add(parameterCode);
1441
1442        return params;
1443    }
1444
1445    protected List<String> testEditParameter(String docId, String parameterName) throws Exception {
1446        selectFrameIframePortlet();
1447        waitAndClickEdit();
1448        waitForPageToLoad();
1449        docId = waitForDocId();
1450        waitAndTypeByName("document.documentHeader.documentDescription", "Editing Test Parameter");
1451        clearTextByName("document.newMaintainableObject.value");
1452        waitAndTypeByName("document.newMaintainableObject.value", "N");
1453        waitAndClickSave();
1454        waitAndClickSubmit();
1455        waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
1456        assertDocSearch(docId, DOC_STATUS_FINAL);
1457        selectTopFrame();
1458        List<String> params = new ArrayList<String>();
1459        params.add(docId);
1460        params.add(parameterName);
1461        return params;
1462    }
1463
1464    protected void testEditRouteRulesDelegation() throws Exception {
1465        waitForPageToLoad();
1466        Thread.sleep(3000);
1467        assertEquals("Kuali Portal Index", getTitle());
1468        selectFrameIframePortlet();
1469        waitAndClickSearch();
1470        waitAndClickEdit();
1471        waitForPageToLoad();
1472        Thread.sleep(3000);
1473        assertTrue(isElementPresentByName(CANCEL_NAME));
1474        waitAndClickCancel();
1475        waitAndClickByName("methodToCall.processAnswer.button0");
1476        waitForPageToLoad();
1477        passed();
1478    }
1479
1480    protected void testFiscalOfficerInfoMaintenanceNew() throws Exception {
1481        selectFrameIframePortlet();
1482        checkForIncidentReport();
1483        String docId = getTextByXpath("//*[@id='u13_control']");
1484        waitAndTypeByXpath("//input[@name='document.documentHeader.documentDescription']", "New FO Doc");
1485        waitAndTypeByXpath("//input[@name='document.newMaintainableObject.dataObject.id']", "5");
1486        waitAndTypeByXpath("//input[@name='document.newMaintainableObject.dataObject.userName']", "Jigar");
1487        waitAndClickByXpath("//button[@id='usave']");
1488        Integer docIdInt = Integer.valueOf(docId).intValue();
1489        waitAndClickActionList();
1490        selectFrameIframePortlet();
1491
1492        if(isElementPresentByLinkText("Last")){
1493            waitAndClickByLinkText("Last");
1494            waitAndClickByLinkText(docIdInt.toString());
1495        } else {
1496            waitAndClickByLinkText(docIdInt.toString());
1497        }
1498
1499        //      ------------------------------- Not working in code when click docId link in list--------------------------
1500        //Thread.sleep(5000);
1501        //String[] windowTitles = getAllWindowTitles();
1502        //selectWindow(windowTitles[1]);
1503        //windowFocus();
1504        //assertEquals(windowTitles[1], getTitle());
1505        //checkForIncidentReport("Action List Id link opened window.", "https://jira.kuali.org/browse/KULRICE-9062 Action list id links result in 404 or NPE");
1506
1507        //------submit-----//
1508        //selectFrame("relative=up");
1509        //waitAndClick("//button[@value='submit']");
1510        //waitForPageToLoad50000();
1511        //close();
1512        //------submit over---//
1513
1514        //----step 2----//
1515        //selectWindow("null");
1516        //windowFocus();
1517        //waitAndClick("//img[@alt='doc search']");
1518        //waitForPageToLoad50000();
1519        //assertEquals(windowTitles[0], getTitle());
1520        //selectFrame("iframeportlet");
1521        //waitAndClick(SEARCH_XPATH);
1522        //waitForPageToLoad50000();
1523        //----step 2 over ----//
1524
1525        //-----Step 3 verifies that doc is final-------//
1526        //assertEquals("FINAL", getText("//table[@id='row']/tbody/tr[1]/td[4]"));
1527        //selectFrame("relative=up");
1528        //waitAndClick("link=Main Menu");
1529        //waitForPageToLoad50000();
1530        //assertEquals(windowTitles[0], getTitle());
1531        //-----Step 3 verified that doc is final -------
1532    }
1533
1534    protected void testIdentityPersonBlanketApprove() throws Exception {
1535        selectFrameIframePortlet();
1536        waitAndCreateNew();
1537        String docId = waitForDocId();
1538        waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Validation Test Person");
1539        assertBlanketApproveButtonsPresent();
1540        waitAndTypeByXpath("//input[@id='document.principalName']", "principal" + RandomStringUtils.randomAlphabetic(3).toLowerCase());
1541        selectByName("newAffln.affiliationTypeCode", "Affiliate");
1542        selectByName("newAffln.campusCode", "BX - BLGTN OFF CAMPUS");
1543        selectByName("newAffln.campusCode", "BL - BLOOMINGTON");
1544        assertElementPresentByName("newAffln.dflt");
1545        waitAndClickByName("newAffln.dflt");
1546        waitAndClickByName("methodToCall.addAffln.anchor");
1547        waitAndClickByName("methodToCall.toggleTab.tabContact");
1548        selectByName("newName.namePrefix", "Mr");
1549        waitAndTypeByName("newName.firstName", "First");
1550        waitAndTypeByName("newName.lastName", "Last");
1551        selectByName("newName.nameSuffix", "Mr");
1552        waitAndClickByName("newName.dflt");
1553        waitAndClickByName("methodToCall.addName.anchor");
1554        waitForPageToLoad();
1555        blanketApproveTest(docId);
1556    }
1557
1558    protected  void testIdentityRoleSaveAndReload()throws Exception{
1559        selectFrameIframePortlet();
1560        waitAndClickSearch2();
1561        waitAndClickByXpath("//a[@title='edit Role withRole=63 ']");
1562        waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Test Save and Reload Role ");
1563        assertBlanketApproveButtonsPresent();
1564        waitAndClickByXpath(SAVE_XPATH_2);
1565        waitForTextPresent("Document was successfully saved.");
1566        waitAndClickByXpath(RELOAD_XPATH);
1567        waitForTextPresent("Document was successfully reloaded.");
1568        findElement(By.xpath("//div[@class='tab-container']")).getText().contains("Members:");
1569        passed();
1570    }
1571
1572    protected void testIdentityRoleBlanketApprove() throws Exception {
1573        selectFrameIframePortlet();
1574        waitAndCreateNew();
1575        waitAndClickByXpath(SEARCH_XPATH, "No search button to click.");
1576        waitAndClickReturnValue();
1577        String docId = waitForDocId();
1578        String dtsTwo = AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomCharsNot9Digits();
1579        waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Validation Test Role " + dtsTwo);
1580        assertBlanketApproveButtonsPresent();
1581        selectByXpath("//select[@id='document.roleNamespace']", LABEL_KUALI_KUALI_SYSTEMS);
1582        waitAndTypeByXpath("//input[@id='document.roleName']", "Validation Test Role " + dtsTwo,
1583                "No Role Name input to type in.");
1584        waitAndClickByName(
1585                "methodToCall.performLookup.(!!org.kuali.rice.kim.impl.identity.PersonImpl!!).(((principalId:member.memberId,principalName:member.memberName))).((``)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;;::::).anchorAssignees");
1586        waitAndClickByXpath(SEARCH_XPATH, "No search button to click.");
1587        waitAndClickReturnValue();
1588        waitAndClickByName("methodToCall.addMember.anchorAssignees");
1589        waitForPageToLoad();
1590        blanketApproveTest(docId);
1591    }
1592
1593    protected void finishBlanketApprovalTest(String docId) throws InterruptedException {
1594        assertBlanketApproveButtonsPresent();
1595        blanketApproveCheck();
1596        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
1597            blanketApproveAssert(docId);
1598        }
1599    }
1600
1601    protected void testLookUp() throws Exception {
1602        waitForPageToLoad();
1603        selectFrameIframePortlet();
1604
1605        // Mixed capitalization
1606        waitAndClick(By.xpath(SEARCH_XPATH_3));
1607        waitAndClickByLinkText(EDIT_LINK_TEXT, "edit button not present does user " + user + " have permission?");
1608        waitForTextPresent("ubmit");
1609        assertTextPresent("ave");
1610        assertTextPresent("pprove");
1611        assertTextPresent("lose");
1612        assertTextPresent("ancel");
1613    }
1614
1615    protected void testReferenceCampusTypeBlanketApprove() throws Exception {
1616        selectFrameIframePortlet();
1617        String randomCode = searchForAvailableCode(1);
1618
1619        waitAndCreateNew();
1620        String docId = waitForDocId();
1621        String dtsTwo = AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomCharsNot9Digits();
1622        waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Validation Test Campus Type " + randomCode + " " + dtsTwo);
1623        waitAndTypeByXpath(DOC_CODE_XPATH, randomCode);
1624        waitAndTypeByXpath("//input[@id='document.newMaintainableObject.name']", "Indianapolis"  + randomCode + dtsTwo);
1625
1626        finishBlanketApprovalTest(docId);
1627    }
1628
1629    protected void performParameterInquiry(String parameterField) throws Exception {
1630        waitAndTypeByName("name", parameterField);
1631        waitAndClickSearch();
1632        isElementPresentByLinkText(parameterField);
1633        waitAndClickByLinkText(parameterField);
1634        waitForPageToLoad();
1635        Thread.sleep(2000);
1636        switchToWindow("Kuali :: Inquiry");
1637        Thread.sleep(2000);
1638    }
1639
1640    protected List<String> testLookUpParameterType(String docId, String parameterType, String parameterCode) throws Exception {
1641        performParameterInquiry(parameterType);
1642        assertEquals(parameterCode, getTextByXpath("//div[@class='tab-container']/table//span[@id='code.div']").trim().toLowerCase());
1643        assertEquals(parameterType, getTextByXpath("//div[@class='tab-container']/table//span[@id='name.div']").trim().toLowerCase());
1644        waitAndClickCloseWindow();
1645        switchToWindow("null");
1646        List<String> params = new ArrayList<String>();
1647        params.add(docId);
1648        params.add(parameterType);
1649        params.add(parameterCode);
1650
1651        return params;
1652    }
1653
1654    protected List<String> testLookUpParameter(String docId, String parameterName) throws Exception {
1655        performParameterInquiry(parameterName);
1656        assertEquals(parameterName, getTextByXpath(
1657                "//div[@class='tab-container']/table//span[@id='name.div']").trim());
1658        assertEquals("Y", getTextByXpath("//div[@class='tab-container']/table//span[@id='value.div']")
1659                .trim());
1660        waitAndClickCloseWindow();
1661        switchToWindow("null");
1662        List<String> params = new ArrayList<String>();
1663        params.add(docId);
1664        params.add(parameterName);
1665
1666        return params;
1667    }
1668
1669    protected void testTermLookupAssertions() throws Exception {
1670        testLookUp();
1671        assertTextPresent("Term Parameters");
1672        waitAndClick(By.xpath(CANCEL2_XPATH));
1673        passed();
1674    }
1675
1676    protected void testTermSpecificationLookupAssertions() throws Exception {
1677        testLookUp();
1678        assertTextPresent("Context");
1679        waitAndClickCancelByText();
1680        passed();
1681    }
1682
1683    protected List<String> testVerifyModifiedParameter(String docId, String parameterName) throws Exception {
1684        performParameterInquiry(parameterName);
1685        assertEquals(parameterName, getTextByXpath("//div[@class='tab-container']/table//span[@id='name.div']").trim());
1686        assertEquals("N", getTextByXpath("//div[@class='tab-container']/table//span[@id='value.div']").trim());
1687        waitAndClickCloseWindow();
1688        switchToWindow("null");
1689        List<String> params = new ArrayList<String>();
1690        params.add(docId);
1691        params.add(parameterName);
1692
1693        return params;
1694    }
1695
1696    protected List<String> testVerifyCopyParameterType(String docId, String parameterType, String parameterCode) throws Exception
1697    {
1698        performParameterInquiry(parameterType);
1699        assertEquals(parameterType, getTextByXpath("//div[@class='tab-container']/table//span[@id='name.div']").trim().toLowerCase());
1700        waitAndClickCloseWindow();
1701        switchToWindow("null");
1702        List<String> params = new ArrayList<String>();
1703        params.add(docId);
1704        params.add(parameterType);
1705        params.add(parameterCode);
1706
1707        return params;
1708    }
1709
1710    protected List<String> testCreateNewPermission(String docId, String permissionName) throws Exception {
1711        waitForPageToLoad();
1712        Thread.sleep(2000);
1713        docId = waitForDocId();
1714        waitAndClickSave();
1715        waitForElementPresentByXpath("//div[contains(.,'Document Description (Description) is a required field.')]/img[@alt='error']");
1716        waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Adding Permission removeme");
1717        waitAndClickSubmit();
1718        waitForElementPresentByXpath("//div[@class='error']");
1719        assertElementPresentByXpath("//div[contains(.,'Template (Template) is a required field.')]/img[@alt='error']");
1720        assertElementPresentByXpath("//div[contains(.,'Permission Namespace (Permission Namespace) is a required field.')]/img[@alt='error']");
1721        assertElementPresentByXpath("//div[contains(.,'Permission Name (Permission Name) is a required field.')]/img[@alt='error']");
1722        selectOptionByName("document.newMaintainableObject.templateId", "36");
1723        selectOptionByName("document.newMaintainableObject.namespaceCode", "KR-SYS");
1724        permissionName = "removeme" + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
1725        waitAndTypeByName("document.newMaintainableObject.name", permissionName);
1726        waitAndTypeByName("document.newMaintainableObject.description", "namespaceCode=KR*");
1727        checkByName("document.newMaintainableObject.active");
1728        waitAndClickSave();
1729        waitForElementPresentByXpath(SAVE_SUCCESSFUL_XPATH);
1730        assertEquals(DOC_STATUS_SAVED, getTextByXpath(DOC_STATUS_XPATH));
1731        waitAndClickSubmit();
1732        waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
1733        assertEquals(DOC_STATUS_ENROUTE, getTextByXpath(DOC_STATUS_XPATH));
1734        List<String> params = new ArrayList<String>();
1735        params.add(docId);
1736        params.add(permissionName);
1737
1738        return params;
1739    }
1740
1741    protected List<String> testLookUpPermission(String docId, String permissionName) throws Exception {
1742        waitAndTypeByName("name", permissionName);
1743        waitAndClickSearch();
1744        isElementPresentByLinkText(permissionName);
1745        List<String> params = new ArrayList<String>();
1746        params.add(docId);
1747        params.add(permissionName);
1748
1749        return params;
1750    }
1751
1752    protected List<String> testEditPermission(String docId, String permissionName) throws Exception {
1753        waitAndClickEdit();
1754        waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Editing Permission removeme");
1755        uncheckByName("document.newMaintainableObject.active");
1756        waitAndClickSubmit();
1757        waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
1758        List<String> params = new ArrayList<String>();
1759        params.add(docId);
1760        params.add(permissionName);
1761
1762        return params;
1763    }
1764
1765    protected List<String> testVerifyPermission(String docId, String permissionName) throws Exception {
1766        waitAndTypeByName("name", permissionName);
1767        waitAndClickByXpath("//input[@title='Active Indicator - No']");
1768        waitAndClickSearch();
1769        isElementPresentByLinkText(permissionName);
1770        List<String> params = new ArrayList<String>();
1771        params.add(docId);
1772        params.add(permissionName);
1773
1774        return params;
1775    }
1776
1777    protected List<String> testCreateNewPerson(String docId, String personName) throws Exception  {
1778        waitForPageToLoad();
1779        docId = waitForDocId();
1780        waitAndTypeByXpath(DOC_DESCRIPTION_XPATH, "Adding Charlie Brown");
1781        waitAndTypeByName("document.documentHeader.explanation", "I want to add Charlie Brown to test KIM");
1782
1783        //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.
1784        personName = "cbrown" + AutomatedFunctionalTestUtils.createUniqueDtsPlusTwoRandomChars();
1785        waitAndTypeByName("document.principalName", personName);
1786        waitAndClickSave();
1787        waitForElementPresentByXpath(SAVE_SUCCESSFUL_XPATH);
1788        assertEquals(DOC_STATUS_SAVED, getTextByXpath(DOC_STATUS_XPATH));
1789        waitAndClickSubmit();
1790        waitForElementPresentByXpath("//div[contains(.,'At least one affiliation must be entered.')]/img[@alt='error']");
1791        assertElementPresentByXpath("//div[contains(.,'At least one name must be entered.')]/img[@alt='error']");
1792        selectOptionByName("newAffln.affiliationTypeCode", "STDNT");
1793        selectOptionByName("newAffln.campusCode", "BL");
1794        checkByName("newAffln.dflt");
1795        waitAndClickByName("methodToCall.addAffln.anchor");
1796        waitAndSelectByName("newName.nameCode", "PRM");
1797        selectOptionByName("newName.namePrefix", "Mr");
1798        waitAndTypeByName("newName.firstName", "Charlie");
1799        waitAndTypeByName("newName.lastName", "Brown");
1800        checkByName("newName.dflt");
1801        waitAndClickByName("methodToCall.addName.anchor");
1802        waitAndClickSubmit();
1803        waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
1804        assertEquals(DOC_STATUS_ENROUTE, getTextByXpath(DOC_STATUS_XPATH));
1805        List<String> params = new ArrayList<String>();
1806        params.add(docId);
1807        params.add(personName);
1808
1809        return params;
1810    }
1811
1812    protected List<String> testLookUpPerson(String docId, String personName) throws Exception {
1813        waitAndTypeByName("principalName", personName);
1814        waitAndClickSearch();
1815        isElementPresentByLinkText(personName);
1816        waitAndClickByName("methodToCall.clearValues");
1817        waitAndTypeByName("firstName", "Charlie");
1818        waitAndClickSearch();
1819        isElementPresentByLinkText(personName);
1820        waitAndClickByName("methodToCall.clearValues");
1821        waitAndTypeByName("lastName", "Brown");
1822        waitAndClickSearch();
1823        isElementPresentByLinkText(personName);
1824        waitAndClickByName("methodToCall.clearValues");
1825        waitAndTypeByName("campusCode", "BL");
1826        waitAndClickSearch();
1827        isElementPresentByLinkText(personName);
1828        List<String> params = new ArrayList<String>();
1829        params.add(docId);
1830        params.add(personName);
1831
1832        return params;
1833    }
1834
1835    protected List<String> testVerifyPerson(String docId, String personName) throws Exception {
1836        waitAndClickByLinkText(personName);
1837        waitForPageToLoad();
1838        Thread.sleep(5000);
1839        switchToWindow("Kuali :: Person");
1840        Thread.sleep(2000);
1841        assertEquals(personName, getTextByXpath("//div[@class='tab-container']/table//tr[2]/td[1]/div").trim());
1842        assertEquals("BL - BLOOMINGTON", getTextByXpath("//div[@class='tab-container']/table[3]//tr[2]/td[2]/div").trim());
1843        assertEquals("Student", getTextByXpath("//select/option[@selected]").trim());
1844        assertElementPresentByXpath("//table[@class='tab']//input[@title='close Overview']");
1845        assertElementPresentByXpath("//table[@class='tab']//input[@title='open Contact']");
1846        assertElementPresentByXpath("//table[@class='tab']//input[@title='open Privacy Preferences']");
1847        assertElementPresentByXpath("//table[@class='tab']//input[@title='open Membership']");
1848        waitAndClickByName("methodToCall.showAllTabs");
1849        waitForElementPresentByXpath("//table[@class='tab']//input[@title='close Overview']");
1850        assertElementPresentByXpath("//table[@class='tab']//input[@title='close Contact']");
1851        assertElementPresentByXpath("//table[@class='tab']//input[@title='close Privacy Preferences']");
1852        assertElementPresentByXpath("//table[@class='tab']//input[@title='close Membership']");
1853        waitAndClickByName("methodToCall.hideAllTabs");
1854        waitForElementPresentByXpath("//table[@class='tab']//input[@title='open Overview']");
1855        assertElementPresentByXpath("//table[@class='tab']//input[@title='open Contact']");
1856        assertElementPresentByXpath("//table[@class='tab']//input[@title='open Privacy Preferences']");
1857        assertElementPresentByXpath("//table[@class='tab']//input[@title='open Membership']");
1858        waitAndClickCloseWindow();
1859        switchToWindow("null");
1860        List<String> params = new ArrayList<String>();
1861        params.add(docId);
1862        params.add(personName);
1863
1864        return params;
1865    }
1866
1867    protected void testConfigurationTestView(String idPrefix) throws Exception {
1868        waitForElementPresentByXpath("//label[@id='" + idPrefix + "TextInputField_label']");
1869
1870        // testing for https://groups.google.com/a/kuali.org/group/rice.usergroup.krad/browse_thread/thread/1e501d07c1141aad#
1871        String styleValue = waitAndGetAttributeByXpath("//label[@id='" + idPrefix + "TextInputField_label']",
1872                "style");
1873
1874        // log.info("styleValue is " + styleValue);
1875        assertTrue(idPrefix + "textInputField label does not contain expected style", styleValue.replace(" ", "").contains("color:red"));
1876
1877        // get current list of options
1878        String refreshTextSelectLocator = "//select[@id='" + idPrefix + "RefreshTextField_control']";
1879        String[] options1 = getSelectOptionsByXpath(refreshTextSelectLocator);
1880        String dropDownSelectLocator = "//select[@id='" + idPrefix + "DropDown_control']";
1881        selectByXpath(dropDownSelectLocator, "Vegetables");
1882        Thread.sleep(3000);
1883
1884        //get list of options after change
1885        String[] options2 = getSelectOptionsByXpath(refreshTextSelectLocator);
1886
1887        //verify that the change has occurred
1888        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",
1889                options1[options1.length - 1].equalsIgnoreCase(options2[options2.length - 1]));
1890
1891        //confirm that control gets disabled
1892        selectByXpath(dropDownSelectLocator, "None");
1893        Thread.sleep(3000);
1894        assertEquals("true", waitAndGetAttributeByXpath(refreshTextSelectLocator, "disabled"));
1895    }
1896
1897    //    protected void testTravelAccountTypeLookup() throws Exception {
1898    //        selectFrameIframePortlet();
1899    //
1900    //        //Blank Search
1901    //        waitAndClickByXpath("//*[contains(button,\"earch\")]/button[1]");
1902    //        Thread.sleep(4000);
1903    //        assertElementPresentByXpath("//table[@class='uif-tableCollectionLayout dataTable']//tr[contains(td[1],'CAT')]");
1904    //        assertElementPresentByXpath("//table[@class='uif-tableCollectionLayout dataTable']//tr[contains(td[1],'EAT')]");
1905    //        assertElementPresentByXpath("//table[@class='uif-tableCollectionLayout dataTable']//tr[contains(td[1],'IAT')]");
1906    //
1907    //        //search with each field
1908    //        waitAndTypeByName("lookupCriteria[accountTypeCode]", "CAT");
1909    //        waitAndClickByXpath("//*[contains(button,\"earch\")]/button[1]");
1910    //        Thread.sleep(2000);
1911    //        assertElementPresentByXpath("//table[@class='uif-tableCollectionLayout dataTable']//tr[contains(td[1],'CAT')]");
1912    //        waitAndClickByXpath("//*[contains(button,\"earch\")]/button[2]");
1913    //        Thread.sleep(2000);
1914    //        waitAndTypeByName("lookupCriteria[name]", "Expense Account Type");
1915    //        waitAndClickByXpath("//*[contains(button,\"earch\")]/button[1]");
1916    //        Thread.sleep(4000);
1917    //        assertElementPresentByXpath("//table[@class='uif-tableCollectionLayout dataTable']//tr[contains(td[1],'EAT')]");
1918    //
1919    //        //Currently No links available for Travel Account Type Inquiry so cant verify heading and values.
1920    //    }
1921
1922    protected void testCategoryLookUp() throws Exception {
1923        waitForPageToLoad();
1924        selectFrameIframePortlet();
1925        waitAndClickByXpath("//button[contains(.,'earch')]");
1926        Thread.sleep(3000);
1927        waitForPageToLoad();
1928        findElement(By.tagName("body")).getText().contains("Actions"); // there are no actions, but the header is the only unique text from searching
1929
1930        // Category's don't have actions (yet)
1931        //waitAndClick("id=u80");
1932        //waitForPageToLoad();
1933        //waitAndClick("id=u86");
1934        //waitForPageToLoad();
1935        //selectWindow("null");
1936        //waitAndClick("xpath=(//input[@name='imageField'])[2]");
1937        //waitForPageToLoad();
1938        //passed();
1939    }
1940
1941    protected void testCreateSampleEDocLite() throws Exception {
1942        waitForPageToLoad();
1943        Thread.sleep(3000);
1944        assertEquals("Kuali Portal Index", getTitle());
1945        selectFrameIframePortlet();
1946        waitAndClickByXpath("//input[@name='methodToCall.search' and @alt='search']");
1947        waitForPageToLoad();
1948
1949        // click on the create new.
1950        waitAndClickByLinkText("Create Document");
1951        waitForPageToLoad();
1952        Thread.sleep(3000);
1953        String docId = getTextByXpath("//table/tbody/tr[4]/td[@class='datacell1']");
1954        waitAndTypeByName("userName", "Viral Chauhan");
1955        waitAndTypeByName("rqstDate", "12/03/2020");
1956        checkByName("fundedBy");
1957        waitAndTypeByName("addText", "Note Added.");
1958        waitAndClickByXpath("//td[@class='datacell']/div/img");
1959        waitAndClickByXpath("//input[@value='submit']");
1960        assertEquals(Boolean.FALSE, (Boolean) isElementPresentByXpath("//input[@value='submit']"));
1961        assertEquals(Boolean.FALSE, (Boolean) isElementPresentByXpath("//input[@value='save']"));
1962        assertEquals(Boolean.FALSE, (Boolean) isElementPresentByXpath("//input[@value='cancel']"));
1963        waitForPageToLoad();
1964        selectTopFrame();
1965        waitAndClickDocSearch();
1966        waitForPageToLoad();
1967        selectFrameIframePortlet();
1968        waitAndClickByXpath("//input[@name='methodToCall.search' and @alt='search']");
1969        waitForElementPresent(By.linkText(docId));
1970    }
1971
1972    protected void testTermLookUp() throws Exception {
1973        testLookUp();
1974        assertTextPresent("Term Parameters");
1975        waitAndClickCancelByText();
1976        passed();
1977    }
1978
1979    protected void testCreateNewRRDTravelRequestDestRouting() throws Exception {
1980        selectFrameIframePortlet();
1981
1982        // Create new Routing Rules Delegation
1983        waitAndClick("img[alt=\"create new\"]");
1984
1985        // Lookup parent rule, click lookup icon
1986        waitAndClickByName(
1987                "methodToCall.performLookup.(!!org.kuali.rice.kew.rule.RuleBaseValues!!).(((id:parentRuleId))).((``)).((<>)).(([])).((**)).((^^)).((&&)).((//)).((~~)).(::::;;::::).anchor");
1988
1989        // Search
1990        waitAndClickByXpath("//td[@class='infoline']/input[@name='methodToCall.search']");
1991
1992        // return value for 1046 TravelRequest.Destination.LasVegas TravelRequest-DestinationRouting
1993        waitAndClick("a[title=\"return valueRule Id=1046 \"]");
1994
1995        // Select the parent rule we just returned
1996        waitAndClickByName("parentResponsibilityId");
1997
1998        // Click continue
1999        waitAndClickByName("methodToCall.createDelegateRule");
2000
2001        waitAndClickCancel();
2002        waitAndClickByName("methodToCall.processAnswer.button0");
2003        waitForPageToLoad();
2004        driver.switchTo().defaultContent();
2005        waitAndClickByXpath("(//input[@name='imageField'])[2]");
2006        passed();
2007    }
2008
2009    protected void testWorkFlowRouteRulesCreateNew() throws Exception {
2010        waitForPageToLoad();
2011        Thread.sleep(5000);
2012        assertEquals("Kuali Portal Index", getTitle());
2013        selectFrameIframePortlet();
2014        waitAndClickCreateNew();
2015        waitAndClickByName(CANCEL_NAME, "https://jira.kuali.org/browse/KULRICE-8161 Work Flow Route Rules cancel new yields 404 not found");
2016
2017        // KULRICE-7753 : WorkFlowRouteRulesIT cancel confirmation missing from create new Route Rules.
2018        waitAndClickByName("methodToCall.processAnswer.button0");
2019        passed();
2020    }
2021
2022    /**
2023     * tests that a Routing Rule maintenance document is created for an edit operation originating
2024     * from a lookup screen
2025     */
2026    protected void testWorkFlowRouteRulesEditRouteRules() throws Exception {
2027        waitForPageToLoad();
2028        assertEquals("Kuali Portal Index", getTitle());
2029        selectFrameIframePortlet();
2030        waitAndClickSearch();
2031        waitAndClickEdit();
2032        waitForPageToLoad();
2033        selectFrameIframePortlet();
2034        waitAndClickCancel();
2035        waitAndClickByName("methodToCall.processAnswer.button0");
2036        passed();
2037    }
2038
2039    /**
2040     * Look at the Location*Aft classes for the current best practices on implementing this method
2041     * @throws InterruptedException
2042     */
2043    protected void createNewEnterDetails() throws InterruptedException {
2044        // overload to utilize
2045        fail("createNewEnterDetails must be implemented by test class");
2046    }
2047
2048    /**
2049     * Look at the Location*Aft classes for the current best practices on implementing this method
2050     * @throws InterruptedException
2051     */
2052    protected void createNewLookupDetails() throws InterruptedException {
2053        // overload to utilize
2054        fail("createNewLookupDetails must be implemented by test class");
2055    }
2056
2057//    protected String createNewTemplateMethod() throws InterruptedException {
2058//        waitAndCreateNew();
2059//        String docId = waitForDocId();
2060//
2061//        createNewEnterDetails();
2062//
2063//        // Ad Hoc Recipients with current user to test Action List
2064//        addAdHocRecipientsPerson(new String[]{getUserName(), "F"}); // FYI
2065//
2066//        waitAndClickSave();
2067//        waitAndClickSubmit();
2068//        waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, CREATE_NEW_DOCUMENT_NOT_SUBMITTED_SUCCESSFULLY_MESSAGE_TEXT);
2069//
2070//        // Action List
2071//        assertActionList(docId, "F", "ENROUTE"); // FYI
2072//
2073//        assertDocSearch(docId, DOC_STATUS_FINAL);
2074//        selectTopFrame();
2075//        return docId;
2076//    }
2077//
2078//    protected String createNewTemplateMethodNoAction() throws InterruptedException {
2079//        waitAndCreateNew();
2080//        String docId = waitForDocId();
2081//
2082//        createNewEnterDetails();
2083//
2084//        waitAndClickSave();
2085//        waitAndClickSubmit();
2086//        waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, CREATE_NEW_DOCUMENT_NOT_SUBMITTED_SUCCESSFULLY_MESSAGE_TEXT);
2087//
2088//        assertDocSearch(docId, DOC_STATUS_FINAL);
2089//        selectTopFrame();
2090//        return docId;
2091//    }
2092
2093    protected void waitAndClickActionList() throws InterruptedException {
2094        WebDriverUtils.jGrowl(driver, "Click Action List", false, "Click Action List");
2095        selectTopFrame();
2096        waitAndClickByXpath("//img[@alt='action list']");
2097    }
2098
2099    protected void testLookUpComponent(String docId, String componentName, String componentCode) throws Exception {
2100        selectFrameIframePortlet();
2101        //Lookup
2102        waitAndTypeByName("name", componentName);
2103        waitAndClickSearch();
2104        isElementPresentByLinkText(componentName);
2105        waitAndClickByLinkText(componentName);
2106        waitForPageToLoad();
2107        Thread.sleep(2000);
2108        switchToWindow("Kuali :: Inquiry");
2109        Thread.sleep(2000);
2110        assertEquals(componentName, getTextByXpath("//div[@class='tab-container']/table//span[@id='name.div']").trim());
2111        assertEquals(componentCode, getTextByXpath("//div[@class='tab-container']/table//span[@id='code.div']").trim());
2112        waitAndClickCloseWindow();
2113        switchToWindow("null");
2114    }
2115
2116    protected void testEditComponent(String docId, String componentName, String componentCode) throws Exception {
2117        selectFrameIframePortlet();
2118        waitAndClickEdit();
2119        waitForPageToLoad();
2120        docId = waitForDocId();
2121        waitAndTypeByName("document.documentHeader.documentDescription", "Editing Test Component");
2122        clearTextByName("document.newMaintainableObject.name");
2123        waitAndTypeByName("document.newMaintainableObject.name", componentName);
2124        waitAndClickSave();
2125        waitAndClickSubmit();
2126        waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
2127        assertDocSearch(docId, DOC_STATUS_FINAL);
2128        selectTopFrame();
2129    }
2130
2131    protected void testCopyComponent(String docId, String componentName, String componentCode) throws Exception {
2132        selectFrameIframePortlet();
2133        waitAndClickCopy();
2134        waitForPageToLoad();
2135        docId = waitForDocId();
2136        waitAndTypeByName("document.documentHeader.documentDescription", "Copying Test Component");
2137        selectOptionByName("document.newMaintainableObject.namespaceCode", "KR-IDM");
2138        waitAndTypeByName("document.newMaintainableObject.code", componentCode);
2139        clearTextByName("document.newMaintainableObject.name");
2140        waitAndTypeByName("document.newMaintainableObject.name", componentName);
2141        waitAndClickSave();
2142        waitAndClickSubmit();
2143        waitForPageToLoad();
2144        checkForDocError();
2145        waitForElementPresentByXpath(DOC_SUBMIT_SUCCESS_MSG_XPATH, "Document is not submitted successfully");
2146        assertDocSearch(docId, DOC_STATUS_FINAL);
2147        selectTopFrame();
2148    }
2149
2150    protected void testVerifyCopyComponent(String docId, String componentName, String componentCode) throws Exception {
2151        selectFrameIframePortlet();
2152        waitAndTypeByName("name", componentName);
2153        waitAndClickSearch();
2154        isElementPresentByLinkText(componentName);
2155        waitAndClickByLinkText(componentName);
2156        waitForPageToLoad();
2157        Thread.sleep(2000);
2158        switchToWindow("Kuali :: Inquiry");
2159        Thread.sleep(2000);
2160        assertEquals(componentName, getTextByXpath("//div[@class='tab-container']/table//span[@id='name.div']").trim());
2161        assertEquals(componentCode, getTextByXpath("//div[@class='tab-container']/table//span[@id='code.div']").trim());
2162        waitAndClickCloseWindow();
2163        switchToWindow("null");
2164    }
2165
2166    protected void testMultiValueSelectAllPages() throws InterruptedException {
2167        waitAndClickButtonByText(SEARCH);
2168        assertButtonDisabledByText(RETURN_SELECTED_BUTTON_TEXT);
2169
2170        // select all, all checkboxes should be checked and return button enabled
2171        waitAndClickDropDown("select all items");
2172        if (!areAllMultiValueSelectsChecked()) {
2173            JiraAwareFailureUtils.fail("select all items failure", this);
2174        }
2175        assertButtonEnabledByText(RETURN_SELECTED_BUTTON_TEXT);
2176
2177        boolean anotherPageOfResults = false;
2178        if (Integer.parseInt(multiValueResultCount()) > 10) {
2179            anotherPageOfResults = true;
2180        }
2181
2182        // all should be checked and button enabled on the next page as well (server side paging)
2183        if (!anotherPageOfResults) {
2184            JiraAwareFailureUtils.fail("select all items server side paging failure not enough results for next page",
2185                    this);
2186        }
2187        waitAndClickByLinkText("Next");
2188
2189        if (!areAllMultiValueSelectsChecked()) {
2190            JiraAwareFailureUtils.fail("select all items server side paging failure", this);
2191        }
2192        assertButtonEnabledByText(RETURN_SELECTED_BUTTON_TEXT);
2193
2194        // deselect all no checkboxes should be checked and return button disabled
2195        waitAndClickDropDown("deselect all items");
2196        if (!areNoMultiValueSelectsChecked()) {
2197            JiraAwareFailureUtils.fail("deselect all items failure", this);
2198        }
2199        assertButtonDisabledByText(RETURN_SELECTED_BUTTON_TEXT);
2200
2201        waitAndClickByLinkText("Previous");
2202        if (!areNoMultiValueSelectsChecked()) {
2203            JiraAwareFailureUtils.fail("deselect all items failure", this);
2204        }
2205        assertButtonDisabledByText(RETURN_SELECTED_BUTTON_TEXT);
2206    }
2207
2208    protected void acceptAlert() {
2209        if (!WebDriverUtils.isAlertPresent(driver)) {
2210            fail("Alert expected but not present for " + this.getClass().getName());
2211        }
2212        WebDriverUtils.alertAccept(driver);
2213    }
2214
2215    protected void testMultiValueSelectAllThisPage() throws InterruptedException {
2216        waitAndClickButtonByText(SEARCH);
2217        assertButtonDisabledByText(RETURN_SELECTED_BUTTON_TEXT);
2218
2219        // select all on this page, all checkboxes should be checked and return button enabled
2220        assertMultiValueSelectAllThisPage();
2221
2222        boolean anotherPageOfResults = false;
2223        if (Integer.parseInt(multiValueResultCount()) > 5) {
2224            anotherPageOfResults = true;
2225        }
2226
2227        // the next page should not have any checkboxes checked return button should still be enabled
2228        waitAndClickByLinkText("Next");
2229        if (!areNoMultiValueSelectsChecked()) {
2230            if (anotherPageOfResults) {
2231                JiraAwareFailureUtils.fail("select all items on this page failure", this);
2232            } else {
2233                JiraAwareFailureUtils.fail("select all items on this page failure not enough results for next page",
2234                        this);
2235            }
2236        }
2237        assertButtonEnabledByText(RETURN_SELECTED_BUTTON_TEXT);
2238
2239        // back to the previous page, checkboxes should be checked and return button enabled still
2240        waitAndClickByLinkText("Previous");
2241        if (!areAllMultiValueSelectsChecked()) {
2242            JiraAwareFailureUtils.fail("select all items on previous page failure", this);
2243        }
2244
2245        // deselect no checkboxes should be checked and the return button should be disabled
2246        assertMultiValueDeselectAllThisPage();
2247    }
2248
2249    /**
2250     * Test the external help on the section and fields
2251     */
2252    protected void testExternalHelp2() throws Exception {
2253        // test external help of section
2254        assertPopUpWindowUrl(By.cssSelector("input[title=\"Help for External Help\"]"), "HelpWindow",
2255                "http://www.kuali.org/?section");
2256
2257        // test external help of field with label left
2258        assertPopUpWindowUrl(By.xpath("//div[@id='field-label-left-external-help']/fieldset/input[@title='Help for Field Label']"), "HelpWindow",
2259                "http://www.kuali.org/?label_left");
2260
2261        // test external help of field with label right
2262        assertPopUpWindowUrl(By.xpath("//div[@id='field-label-right-external-help']/fieldset/input[@title='Help for Field Label']"), "HelpWindow",
2263                "http://www.kuali.org/?label_right");
2264
2265        // test external help of field with label top and help URL from system parameters
2266        assertPopUpWindowUrl(By.xpath("//div[@id='field-label-top-external-help']/fieldset/input[@title='Help for Field Label']"), "HelpWindow",
2267                "http://www.kuali.org/?system_parm");
2268
2269        // test external help of standalone help widget
2270        assertPopUpWindowUrl(By.id("standalone-external-help"), "HelpWindow", "http://www.kuali.org/?widget_only");
2271    }
2272
2273    /**
2274     * Test the external help on the sub-section and display only fields
2275     */
2276
2277    protected void testDisplayOnlyExternalHelp2() throws Exception {
2278        // test external help of sub-section
2279        assertPopUpWindowUrl(By.cssSelector("input[title=\"Help for Display only fields\"]"), "HelpWindow", "http://www.kuali.org/?sub_section");
2280
2281        // test external help of display only data field
2282        assertPopUpWindowUrl(By.xpath(
2283                "//div[@id='display-field-external-help']/fieldset/input[@title='Help for Field Label']"), "HelpWindow",
2284                "http://www.kuali.org/?display_field");
2285    }
2286
2287    /**
2288     * Test the external help on the section and fields with missing help URL
2289     */
2290
2291    protected void testMissingExternalHelp2() throws Exception {
2292        // test external help of section is not rendered
2293        assertFalse(isElementPresent(By.cssSelector("input[title=\"Help for Missing External Help\"]")));
2294
2295        // test external help of field with blank externalHelpURL is not rendered
2296        assertFalse(isElementPresentByXpath("//div[@id='external-help-externalHelpUrl-empty']/*[@class='uif-helpImage']"));
2297
2298        // test external help of field with empty helpDefinition is not rendered
2299        assertFalse(isElementPresentByXpath("//div[@id='external-help-helpdefinition-empty']/*[@class='uif-helpImage']"));
2300
2301        // test external help of field with missing system parameter is not rendered
2302        assertFalse(isElementPresentByXpath("//div[@id='external-help-system-parm-missing']/*[@class='uif-helpImage']"));
2303
2304        // test external help of standalone help widget is not rendered
2305        assertFalse(isElementPresentByXpath("//div[@id='standalone-external-help-missing']"));
2306    }
2307
2308    private String searchForAvailableCode(int codeLength) throws InterruptedException {
2309        String randomCode = RandomStringUtils.randomAlphabetic(codeLength).toUpperCase();
2310        waitAndTypeByName("code", randomCode);
2311        waitAndClickSearch();
2312        int attemptCount = 1;
2313        waitForTextPresent("You have entered the primary key for this table");
2314        while (!isTextPresent("No values match this search.") && attemptCount < 25) {
2315            randomCode = Character.toString((char) (randomCode.toCharArray()[0] + attemptCount++));
2316            clearTextByName("code");
2317            waitAndTypeByName("code", randomCode);
2318            waitAndClickSearch();
2319            waitForTextPresent("You have entered the primary key for this table");
2320        }
2321        return randomCode;
2322    }
2323
2324    protected void testSearchEditCancel() throws InterruptedException {
2325        selectFrameIframePortlet();
2326        waitAndClickSearch2();
2327        waitAndClickEdit();
2328        testCancelConfirmation();
2329    }
2330
2331    protected void testServerErrorsIT() throws Exception {
2332        waitAndClickByXpath("//button[contains(.,'Get Error Messages')]");
2333        waitForElementPresent("div[data-messages_for=\"Demo-ValidationLayout-SectionsPage\"] .uif-errorMessageItem-field");
2334        waitIsVisibleByXpath("//header[@data-header_for='Demo-ValidationLayout-Section1']");
2335        assertElementPresentByXpath("//*[@data-messageitemfor='Demo-ValidationLayout-Section1' and @class='uif-errorMessageItem']");
2336        assertElementPresent("div[data-role=\"InputField\"] img[alt=\"Error\"]");
2337        assertElementPresentByXpath("//a[contains(.,'Section 1 Title')]");
2338        fireMouseOverEventByXpath("//a[contains(.,'Field 1')]");
2339        assertElementPresent(".uif-errorMessageItem-field");
2340        waitAndClickByXpath("//a[contains(.,'Field 1')]");
2341        waitIsVisible(".popover");
2342        waitIsVisible(".popover-content > .uif-serverMessageItems");
2343        waitIsVisible(".popover-content > .uif-serverMessageItems .uif-errorMessageItem-field");
2344        waitAndTypeByName("field1", "");
2345        fireEvent("field1", "blur");
2346        fireEvent("field1", "focus");
2347        waitIsVisible(".popover");
2348        waitIsVisible(".popover-content > .uif-serverMessageItems .uif-errorMessageItem-field");
2349        waitIsVisible(".popover-content > .uif-clientMessageItems");
2350        waitIsVisible(".popover-content > .uif-clientMessageItems  .uif-errorMessageItem-field");
2351        waitAndTypeByName("field1", "t");
2352
2353        for (int second = 0;; second++) {
2354            if (second >= waitSeconds) {
2355                jiraAwareFail(TIMEOUT_MESSAGE);
2356            }
2357            try {
2358                if (!isElementPresent(".popover-content > .uif-clientMessageItems")) {
2359                    break;
2360                }
2361            } catch (Exception e) {}
2362            Thread.sleep(1000);
2363        }
2364
2365        waitIsVisible(".popover-content > .uif-serverMessageItems .uif-errorMessageItem-field");
2366        assertFalse(isElementPresent(".popover-content > .uif-clientMessageItems"));
2367    }
2368
2369    protected void testServerInfoIT() throws Exception {
2370        waitAndClickByXpath("//button[contains(.,'Get Info Messages')]");
2371        waitIsVisibleByXpath("//div[@data-messages_for='Demo-ValidationLayout-SectionsPage']");
2372        waitForProgressLoading();
2373        assertTrue(isVisibleByXpath("//div[@data-messages_for='Demo-ValidationLayout-SectionsPage']"));
2374        assertTrue(isElementPresent(
2375                "div[data-messages_for=\"Demo-ValidationLayout-SectionsPage\"] .uif-infoMessageItem"));
2376        assertTrue(isVisible("div[data-messages_for=\"Demo-ValidationLayout-Section1\"]"));
2377        assertTrue(isElementPresent("div[data-messages_for=\"Demo-ValidationLayout-Section1\"] .uif-infoMessageItem"));
2378        assertTrue(isElementPresentByXpath("//div[@data-role='InputField']//img[@alt='Information']"));
2379        fireMouseOverEventByXpath("//a[contains(.,'Field 1')]");
2380        assertTrue(isElementPresent(".uif-infoHighlight"));
2381        waitAndClickByXpath("//a[contains(.,'Field 1')]");
2382        waitForElementPresentByXpath("//div[@class='popover top in uif-tooltip-info-ss']");
2383        waitAndTypeByName("field1", "");
2384        fireEvent("field1", "blur");
2385        fireEvent("field1", "focus");
2386        waitForElementPresentByXpath("//div[@class='popover uif-tooltip-info-ss top in uif-tooltip-error-ss']");
2387        waitAndTypeByName("field1", "b");
2388        fireEvent("field1", "blur");
2389        fireEvent("field1", "focus");
2390        waitForElementPresentByXpath("//div[@class='popover uif-tooltip-error-ss top in uif-tooltip-info-ss']");
2391        fireEvent("field1", "focus");
2392        clearTextByName("field1");
2393        fireEvent("field1", "blur");
2394        waitForElementPresentByXpath("//div[@class='popover uif-tooltip-info-ss top in uif-tooltip-error-ss']");
2395    }
2396
2397    protected void testServerWarningsIT() throws Exception {
2398        waitAndClickByXpath("//button[contains(.,'Get Warning Messages')]");
2399        waitForElementPresentByXpath("//div[@id='Demo-ValidationLayout-SectionsPage_messages']");
2400        waitForElementPresentByXpath("//div[@id='Demo-ValidationLayout-Section1_messages']");
2401        waitForElementPresentByXpath("//a[contains(.,'Field 1')]");
2402        fireMouseOverEventByXpath("//a[contains(.,'Field 1')]");
2403        waitForElementPresentByXpath(
2404                "//div[@class='uif-inputField uif-boxLayoutHorizontalItem uif-hasWarning uif-warningHighlight']");
2405        waitAndClickByXpath("//a[contains(.,'Field 1')]");
2406        waitForElementPresentByXpath("//div[@class='popover uif-tooltip-warning-ss top in uif-tooltip-error-ss']");
2407        waitAndTypeByName("field1", "");
2408        fireEvent("field1", "blur");
2409        fireMouseOverEventByName("field1");
2410        waitForElementPresentByXpath("//div[@class='popover uif-tooltip-warning-ss top in uif-tooltip-error-ss']");
2411        waitAndTypeByName("field1", "b");
2412        fireEvent("field1", "blur");
2413        fireMouseOverEventByName("field1");
2414        waitForElementPresentByXpath("//div[@class='popover uif-tooltip-warning-ss top in uif-tooltip-error-ss']");
2415        clearTextByName("field1");
2416        fireEvent("field1", "blur");
2417        fireMouseOverEventByName("field1");
2418        waitForElementPresentByXpath("//div[@class='popover uif-tooltip-warning-ss top in uif-tooltip-error-ss']");
2419        passed();
2420    }
2421
2422    /**
2423     * Test the tooltip and external help on the view
2424     */
2425    protected void testViewHelp2() throws Exception {
2426        // test tooltip help
2427        if (isElementPresentByXpath("//td[@class='jquerybubblepopup-innerHtml']")) {
2428            assertFalse(findElement(By.cssSelector("td.jquerybubblepopup-innerHtml")).isDisplayed());
2429        }
2430
2431        // test tooltip help
2432        fireMouseOverEventByXpath("//h1/span[@class='uif-headerText-span']");
2433        Thread.sleep(2000);
2434        assertTrue(isVisibleByXpath("//td[contains(text(),'View help')]"));
2435        assertPopUpWindowUrl(By.cssSelector("input[title=\"Help for Configuration Test View\"]"), "HelpWindow", "http://www.kuali.org/");
2436    }
2437
2438    protected void testVerifyAddDeleteFiscalOfficerLegacy() throws Exception {
2439        selectFrameIframePortlet();
2440        waitAndTypeByName("document.documentHeader.documentDescription", AutomatedFunctionalTestUtils
2441                .createUniqueDtsPlusTwoRandomChars());
2442        waitAndTypeByName("newCollectionLines['document.newMaintainableObject.dataObject.fiscalOfficer.accounts'].number","1234567890");
2443        waitAndTypeByName("newCollectionLines['document.newMaintainableObject.dataObject.fiscalOfficer.accounts'].foId", "2");
2444        waitAndClickByXpath("//button[@data-loadingmessage='Adding Line...']");
2445        waitForElementPresentByName("document.newMaintainableObject.dataObject.fiscalOfficer.accounts[0].number");
2446        assertEquals("1234567890", waitAndGetAttributeByName(
2447                "document.newMaintainableObject.dataObject.fiscalOfficer.accounts[0].number", "value"));
2448        assertEquals("2", waitAndGetAttributeByName(
2449                "document.newMaintainableObject.dataObject.fiscalOfficer.accounts[0].foId", "value"));
2450        waitAndClickByXpath("//button[@data-loadingmessage='Deleting Line...']");
2451        Thread.sleep(3000);
2452        assertEquals(Boolean.FALSE, (Boolean) isElementPresentByName(
2453                "document.newMaintainableObject.dataObject.fiscalOfficer.accounts[0].number"));
2454        passed();
2455    }
2456
2457    protected void testVerifyAddDeleteNoteLegacy() throws Exception {
2458        selectFrameIframePortlet();
2459        waitAndClick(
2460                "div.tableborders.wrap.uif-boxLayoutVerticalItem.clearfix  span.uif-headerText-span > img.uif-disclosure-image");
2461        waitForElementPresent("button[title='Add a Note'].uif-action.uif-primaryActionButton.uif-smallActionButton");
2462        waitAndClickByName("newCollectionLines['document.notes'].noteText");
2463        waitAndTypeByName("newCollectionLines['document.notes'].noteText", "Test note");
2464        waitAndClick("button[title='Add a Note'].uif-action.uif-primaryActionButton.uif-smallActionButton");
2465        //        waitForElementPresentByName("document.notes[0].noteText");
2466        assertEquals("Test note", getTextByXpath("//pre"));
2467        waitAndClick("button[title='Delete a Note'].uif-action.uif-primaryActionButton.uif-smallActionButton");
2468        assertEquals(Boolean.FALSE, (Boolean) isElementPresentByName("document.notes[0].noteText"));
2469        passed();
2470    }
2471
2472    protected void testVerifyAdHocRecipientsLegacy() throws Exception {
2473        selectFrameIframePortlet();
2474        waitAndClickByLinkText("Fiscal Officer Accounts");
2475        assertElementPresentByXpath(
2476                "//select[@name=\"newCollectionLines['document.adHocRoutePersons'].actionRequested\"]");
2477        assertElementPresentByXpath(
2478                "//input[@name=\"newCollectionLines['document.adHocRoutePersons'].name\" and @type=\"text\"]");
2479        assertElementPresentByXpath(
2480                "//select[@name=\"newCollectionLines['document.adHocRouteWorkgroups'].actionRequested\"]");
2481        assertElementPresentByXpath(
2482                "//input[@name=\"newCollectionLines['document.adHocRouteWorkgroups'].recipientNamespaceCode\" and @type='text']");
2483        assertElementPresentByXpath(
2484                "//input[@name=\"newCollectionLines['document.adHocRouteWorkgroups'].recipientName\" and @type='text']");
2485        passed();
2486    }
2487
2488    protected void testVerifyButtonsLegacy() throws Exception {
2489        selectFrameIframePortlet();
2490        assertElementPresentByXpath("//button[contains(.,'ubmit')]");
2491        assertElementPresentByXpath("//button[contains(.,'ave')]");
2492        assertElementPresentByXpath("//button[contains(.,'lanket approve')]");
2493        assertElementPresentByXpath("//button[contains(.,'lose')]");
2494        assertElementPresentByXpath("//a[contains(.,'ancel')]");
2495        passed();
2496    }
2497
2498    protected void testVerifyConstraintText() throws Exception {
2499        selectFrameIframePortlet();
2500        assertEquals("* indicates required field", getText(
2501                "div.uif-boxLayout.uif-horizontalBoxLayout.clearfix > span.uif-message.uif-requiredInstructionsMessage.uif-boxLayoutHorizontalItem"));
2502        assertEquals("Must not be more than 10 characters", getText(
2503                "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"));
2504        assertEquals("Must not be more than 10 characters", getText(
2505                "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"));
2506        assertEquals("Must not be more than 10 characters", getText(
2507                "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"));
2508        passed();
2509    }
2510
2511    protected void testVerifyEditedComponent(String docId, String componentName, String componentCode) throws Exception {
2512        selectFrameIframePortlet();
2513        waitAndTypeByName("name", componentName);
2514        waitAndClickSearch();
2515        isElementPresentByLinkText(componentName);
2516        waitAndClickByLinkText(componentName);
2517        waitForPageToLoad();
2518        Thread.sleep(2000);
2519        switchToWindow("Kuali :: Inquiry");
2520        Thread.sleep(2000);
2521        assertEquals(componentName, getTextByXpath("//div[@class='tab-container']/table//span[@id='name.div']").trim());
2522        assertEquals(componentCode, getTextByXpath("//div[@class='tab-container']/table//span[@id='code.div']").trim());
2523        waitAndClickCloseWindow();
2524        switchToWindow("null");
2525        List<String> parameterList=new ArrayList<String>();
2526    }
2527
2528    protected void testVerifyDisclosures() throws Exception {
2529        selectFrameIframePortlet();
2530        assertElementPresentByXpath("//span[contains(text(),'Document Overview')]");
2531        assertElementPresentByXpath("//span[contains(text(),'Document Overview')]");
2532        assertElementPresentByXpath("//span[contains(text(),'Account Information')]");
2533        assertElementPresentByXpath("//span[contains(text(),'Fiscal Officer Accounts')]");
2534        assertElementPresentByXpath("//span[contains(text(),'Notes and Attachments')]");
2535        assertElementPresentByXpath("//span[contains(text(),'Ad Hoc Recipients')]");
2536        assertElementPresentByXpath("//span[contains(text(),'Route Log')]");
2537        colapseExpandByXpath("//span[contains(text(),'Document Overview')]//img",
2538                "//label[contains(text(),'Organization Document Number')]");
2539        colapseExpandByXpath("//span[contains(text(),'Account Information')]//img",
2540                "//label[contains(text(),'Travel Account Type Code')]");
2541        colapseExpandByXpath("//span[contains(text(),'Fiscal Officer Accounts')]//img",
2542                "//a[contains(text(),'Lookup/Add Multiple Lines')]");
2543        expandColapseByXpath("//span[contains(text(),'Notes and Attachments')]//img",
2544                "//label[contains(text(),'Note Text')]");
2545        expandColapseByXpath("//span[contains(text(),'Ad Hoc Recipients')]",
2546                "//span[contains(text(),'Ad Hoc Group Requests')]");
2547
2548        // Handle frames
2549        waitAndClickByXpath("//span[contains(text(),'Route Log')]//img");
2550        selectFrame("routeLogIFrame");
2551        waitIsVisibleByXpath("//img[@alt='refresh']");
2552
2553        // relative=top iframeportlet might look weird but either alone results in something not found.
2554        selectTopFrame();
2555        selectFrameIframePortlet();
2556        waitAndClickByXpath("//span[contains(text(),'Route Log')]//img");
2557        selectFrame("routeLogIFrame");
2558        waitNotVisibleByXpath("//img[@alt='refresh']");
2559        passed();
2560    }
2561
2562    protected void testVerifyDocumentOverviewLegacy() throws Exception {
2563        selectFrameIframePortlet();
2564        assertTextPresent("Document Overview");
2565        assertElementPresentByXpath("//input[@name='document.documentHeader.documentDescription']");
2566        assertElementPresentByXpath("//input[@name='document.documentHeader.organizationDocumentNumber']");
2567        assertElementPresentByXpath("//textarea[@name='document.documentHeader.explanation']");
2568        passed();
2569    }
2570
2571    protected void testVerifyExpandCollapse() throws Exception {
2572        selectFrameIframePortlet();
2573        assertElementPresentByXpath("//button[contains(@class, 'uif-expandDisclosuresButton')]");
2574        assertElementPresentByXpath("//button[contains(@class, 'uif-collapseDisclosuresButton')]");
2575        passed();
2576    }
2577
2578    protected void testVerifyFieldsLegacy() throws Exception {
2579        selectFrameIframePortlet();
2580        assertElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.number' and @type='text' and @size=10 and @maxlength=10]");
2581        assertElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.extension.accountTypeCode' and @type='text' and @size=2 and @maxlength=3]");
2582        assertElementPresentByXpath(
2583                "//input[@name='document.newMaintainableObject.dataObject.subAccount' and @type='text' and @size=10 and @maxlength=10]");
2584        assertElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.subsidizedPercent' and @type='text' and @size=6 and @maxlength=20]");
2585        assertElementPresentByXpath(
2586                "//input[@name='document.newMaintainableObject.dataObject.foId' and @type='text' and @size=5 and @maxlength=10]");
2587        assertElementPresentByXpath(
2588                "//input[@name=\"newCollectionLines['document.newMaintainableObject.dataObject.fiscalOfficer.accounts'].number\" and @type='text' and @size=10 and @maxlength=10]");
2589        assertElementPresentByXpath(
2590                "//input[@name=\"newCollectionLines['document.newMaintainableObject.dataObject.fiscalOfficer.accounts'].foId\" and @type='text' and @size=5 and @maxlength=10]");
2591        passed();
2592    }
2593
2594    protected void testVerifyHeaderFieldsLegacy() throws Exception {
2595        selectFrameIframePortlet();
2596        assertElementPresentByXpath("//div[contains(@class, 'uif-documentNumber')]");
2597        assertElementPresentByXpath("//div[contains(@class, 'uif-documentInitiatorNetworkId')]");
2598        assertElementPresentByXpath("//div[contains(@class, 'uif-documentStatus')]");
2599        assertElementPresentByXpath("//div[contains(@class, 'uif-documentCreateDate')]");
2600        passed();
2601    }
2602
2603    protected void testVerifyLookupAddMultipleLinesLegacy() throws Exception {
2604        selectFrameIframePortlet();
2605        assertElementPresentByXpath("//a[contains(text(),'Lookup/Add Multiple Lines')]");
2606        passed();
2607    }
2608
2609    protected void testVerifyNotesAndAttachments() throws Exception {
2610        selectFrameIframePortlet();
2611        waitAndClickByXpath("//span[contains(text(),'Notes and Attachments')]");
2612        waitForElementPresentByXpath("//button[@title='Add a Note']");
2613        assertElementPresentByXpath("//span[contains(text(),'Notes and Attachments')]");
2614        assertElementPresentByXpath("//textarea[@name=\"newCollectionLines['document.notes'].noteText\"]");
2615        assertElementPresentByXpath("//input[@name='attachmentFile']");
2616
2617        //assertElementPresentByXpath("//input[@name=\"newCollectionLines['document.notes'].attachment.attachmentTypeCode\"]");
2618        passed();
2619    }
2620
2621    protected void testVerifyQuickfinderIconsLegacy() throws Exception {
2622        selectFrameIframePortlet();
2623        assertTextPresent("Document Overview");
2624        assertElementPresentByXpath("//*[@id='quickfinder1']");
2625        assertElementPresentByXpath("//*[@id='quickfinder2']");
2626        assertElementPresentByXpath("//*[@id='quickfinder3']");
2627        assertElementPresentByXpath("//*[@id='quickfinder4_add']");
2628
2629        // TODO it would be better to test that the image isn't 404
2630        passed();
2631    }
2632
2633    protected void testVerifyRouteLog() throws Exception {
2634        selectFrameIframePortlet();
2635        waitAndClickByLinkText("Route Log");
2636        waitForElementPresent("//iframe[contains(@src,'RouteLog.do')]");
2637        passed();
2638    }
2639
2640    protected void testVerifySave() throws Exception {
2641        selectFrameIframePortlet();
2642        waitAndTypeByName("document.documentHeader.documentDescription",
2643                "Test Document " + AutomatedFunctionalTestUtils.DTS);
2644        waitAndClickByName("document.newMaintainableObject.dataObject.number");
2645        waitAndTypeByName("document.newMaintainableObject.dataObject.number", "1234567890");
2646        waitAndTypeByName("document.newMaintainableObject.dataObject.extension.accountTypeCode", "EAT");
2647        waitAndTypeByName("document.newMaintainableObject.dataObject.subAccount", "a1");
2648        waitAndClick(
2649                "button[data-loadingmessage='Saving...'].uif-action.uif-primaryActionButton.uif-boxLayoutHorizontalItem");
2650        Thread.sleep(2000);
2651
2652        // checkErrorMessageItem(" also digit validation jira https://jira.kuali.org/browse/KULRICE-8038");
2653        passed();
2654    }
2655
2656    protected void testVerifySubsidizedPercentWatermarkLegacy() throws Exception {
2657        selectFrameIframePortlet();
2658
2659        // May be blowing up due to multiple locators
2660        //assertTrue(isElementPresent("//input[@name='document.newMaintainableObject.dataObject.subsidizedPercent' and @type='text' and @placeholder='##.##   ']"));
2661        assertElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.subsidizedPercent']");
2662        passed();
2663    }
2664
2665    protected void typeEnter() {
2666        jGrowl("Press Enter");
2667        driver.switchTo().activeElement().sendKeys(Keys.ENTER);
2668    }
2669
2670    protected void typeTab() {
2671        jGrowl("Press Tab");
2672        driver.switchTo().activeElement().sendKeys(Keys.TAB);
2673    }
2674
2675    protected void uncheck(By by) throws InterruptedException {
2676        WebElement element = findElement(by);
2677        if (element.isSelected()) {
2678            element.click();
2679        }
2680    }
2681
2682    protected void uncheckByName(String name) throws InterruptedException {
2683        uncheck(By.name(name));
2684    }
2685
2686    protected void uncheckByXpath(String locator) throws InterruptedException {
2687        uncheck(By.xpath(locator));
2688    }
2689
2690    protected void verifyRichMessagesValidationBasicFunctionality() throws Exception {
2691        assertTrue(isElementPresentByXpath("//input[@type='text' and @name='field1']"));
2692        assertTrue(isElementPresentByXpath("//a[contains(text(), 'Kuali')]"));
2693        assertTrue(isElementPresentByXpath("//input[@type='checkbox' and @name='field2']"));
2694        Thread.sleep(3000);
2695    }
2696
2697    protected void verifyRichMessagesValidationAdvancedFunctionality() throws Exception {
2698        //Color Options
2699        assertTrue(isElementPresentByXpath("//span[@style='color: green;']"));
2700        assertTrue(isElementPresentByXpath("//span[@style='color: blue;']"));
2701
2702        //Css class
2703        assertTrue(isElementPresentByXpath("//span[@class='uif-text-underline uif-text-larger']"));
2704
2705        //Combinations
2706        assertTrue(isElementPresentByXpath("//input[@type='text' and @name='field3']"));
2707        assertTrue(isElementPresentByXpath("//select[@name='field4']"));
2708        assertTrue(isElementPresentByXpath("//button[contains(text(), 'Action Button')]"));
2709
2710        //Rich Message Field
2711        assertTrue(isElementPresentByXpath("//label[contains(., 'Label With')]/span[contains(., 'Color')]"));
2712        assertTrue(isElementPresentByXpath("//label[contains(., 'Label With')]/i/b[contains(., 'Html')]"));
2713        assertTrue(isElementPresentByXpath("//label[contains(., 'Label With')]/img[@class='uif-image inlineBlock']"));
2714        Thread.sleep(3000);
2715    }
2716
2717    protected void verifyRichMessagesValidationLettersNumbersValidation() throws Exception {
2718        //For letters only Validation
2719        assertTrue(isElementPresentByXpath("//div[@data-parent='Demo-AdvancedMessagesSection']/div/input[@type='text' and @name='field5']"));
2720        waitAndTypeByXpath(
2721                "//div[@data-parent='Demo-AdvancedMessagesSection']/div/input[@type='text' and @name='field5']", "abc");
2722        assertFalse(isElementPresentByXpath("//div[@class='uif-field uif-inputField uif-inputField-labelTop inlineBlock uif-hasError']"));
2723        clearTextByXpath(
2724                "//div[@data-parent='Demo-AdvancedMessagesSection']/div/input[@type='text' and @name='field5']");
2725        waitAndTypeByXpath("//div[@data-parent='Demo-AdvancedMessagesSection']/div/input[@type='text' and @name='field5']","abc12");
2726        waitAndTypeByXpath("//input[@name= 'field6']", "");
2727        waitForElementPresentByXpath("//div[@class='uif-inputField inlineBlock uif-hasError']");
2728        Thread.sleep(3000);
2729        clearTextByXpath("//div[@data-parent='Demo-AdvancedMessagesSection']/div/input[@type='text' and @name='field5']");
2730        waitAndTypeByXpath("//div[@data-parent='Demo-AdvancedMessagesSection']/div/input[@type='text' and @name='field5']","abc");
2731        waitAndTypeByXpath("//input[@name= 'field6']", "");
2732
2733        //For numbers only validation
2734        waitAndTypeByXpath("//input[@name= 'field6']", "123");
2735        assertFalse(isElementPresentByXpath("//div[@class='uif-field uif-inputField uif-inputField-labelTop inlineBlock uif-hasError']"));
2736        clearTextByXpath("//input[@name='field6']");
2737        waitAndTypeByXpath("//input[@name='field6']", "123ab");
2738        fireEvent("field6", "blur");
2739        waitForElementPresentByXpath("//div[@class='uif-inputField inlineBlock uif-hasError']");
2740    }
2741
2742    protected void verifyRichMessagesValidationRadioAndCheckBoxGroupFunctionality() throws Exception {
2743        //Radio Group
2744        assertTrue(isElementPresentByXpath("//fieldset[@class='uif-verticalRadioFieldset']/span/input[@type='radio' and @name='field24' and @value='1']"));
2745        assertTrue(isElementPresentByXpath(
2746                "//fieldset[@class='uif-verticalRadioFieldset']/span/input[@type='radio' and @name='field24' and @value='2']"));
2747        assertTrue(isElementPresentByXpath(
2748                "//fieldset[@class='uif-verticalRadioFieldset']/span/input[@type='radio' and @name='field24' and @value='3']"));
2749        assertTrue(isElementPresentByXpath(
2750                "//fieldset[@class='uif-verticalRadioFieldset']/span/input[@type='radio' and @name='field24' and @value='4']"));
2751
2752        //Checkbox Group
2753        assertTrue(isElementPresentByXpath(
2754                "//fieldset[@class='uif-verticalCheckboxesFieldset']/span/input[@type='checkbox' and @name='field115' and @value='1']"));
2755        assertTrue(isElementPresentByXpath(
2756                "//fieldset[@class='uif-verticalCheckboxesFieldset']/span/input[@type='checkbox' and @name='field115' and @value='2']"));
2757        assertTrue(isElementPresentByXpath(
2758                "//fieldset[@class='uif-verticalCheckboxesFieldset']/span/input[@type='checkbox' and @name='field115' and @value='3']"));
2759        assertTrue(isElementPresentByXpath(
2760                "//fieldset[@class='uif-verticalCheckboxesFieldset']/span/label/div/select[@name='field4']"));
2761
2762        //Checkbox Control
2763        assertTrue(isElementPresentByXpath("//input[@type='checkbox' and @name='bField1']"));
2764        assertTrue(isElementPresentByXpath("//input[@type='text' and @name='field103']"));
2765    }
2766
2767    protected void verifyRichMessagesValidationLinkDeclarationsFunctionality() throws Exception {
2768        //Testing link tag
2769        waitAndClickByLinkText("Kuali Site");
2770        Thread.sleep(9000);
2771        switchToWindow("Open Source Software | www.kuali.org");
2772        switchToWindow(RICH_MESSAGES_WINDOW_TITLE);
2773
2774        //Testing methodToCall Action
2775        waitAndClickByXpath("//p[contains(., 'Testing methodToCall action')]/a");
2776        Thread.sleep(3000);
2777        assertTrue(isElementPresentByXpath(
2778                "//div[@class='alert alert-danger']"));
2779
2780        //Testing methodToCall action (no client validation check)
2781        waitAndClickByXpath("//p[contains(., 'Testing methodToCall action (no client validation check)')]/a");
2782        assertTrue(isElementPresentByXpath("//div[@id='Demo-BasicMessagesSection_messages' and @class='alert alert-danger']"));
2783        assertTrue(isElementPresentByXpath("//div[@id='Demo-AdvancedMessagesSection_messages' and @class='alert alert-danger']"));
2784        Thread.sleep(3000);
2785    }
2786
2787    protected void waitAndClickAdministration() throws InterruptedException {
2788        waitAndClickByLinkText(ADMINISTRATION_LINK_TEXT, this);
2789    }
2790
2791    protected void waitAndClickClearValues() throws InterruptedException {
2792        waitAndClickButtonByText("Clear Values");
2793    }
2794
2795    /**
2796     * {@link #ADMINISTRATION_LINK_TEXT}
2797     * @param failable
2798     * @throws InterruptedException
2799     */
2800    private void waitAndClickAdministration(JiraAwareFailable failable) throws InterruptedException {
2801        waitAndClickByLinkText(ADMINISTRATION_LINK_TEXT, failable);
2802    }
2803
2804    protected void waitAndCancelConfirmation() throws InterruptedException {
2805        waitAndClickCancel();
2806        waitAndClickByName("methodToCall.processAnswer.button0");
2807    }
2808
2809    protected void waitAndClickAdHocPersonAdd() throws InterruptedException  {
2810        jGrowl("Click AdHoc Person add");
2811        waitAndClickByXpath("//button[@id='Uif-AdHocPersonCollection_add']");
2812    }
2813
2814    protected void waitAndClickAdHocPersonAddQuickFinder() throws InterruptedException  {
2815        jGrowl("Click AdHoc Person quickfinder");
2816        waitAndClickByXpath("//div[@data-parent='Uif-AdHocPersonCollection']/div/div/button");
2817    }
2818
2819    protected void waitAndClickAdHocGroupAddQuickFinder() throws InterruptedException  {
2820        jGrowl("Click AdHoc Group quickfinder");
2821        waitAndClickByXpath("//div[@data-parent='CollectionGroup_AdHocWorkgroup']/div/div/button");
2822    }
2823
2824    protected void waitAndClickBlanketApprove() throws InterruptedException {
2825        waitAndClickButtonByText("Blanket Approve");
2826    }
2827
2828    /**
2829     * {@link #CANCEL_NAME}
2830     * @throws InterruptedException
2831     */
2832    protected void waitAndClickCancel() throws InterruptedException {
2833        waitAndClickByName(CANCEL_NAME);
2834    }
2835
2836    protected void waitAndClickCancelByText() throws InterruptedException {
2837        waitAndClickButtonByText("Cancel");
2838    }
2839
2840    /**
2841     * {@link #CLOSE_WINDOW_XPATH_TITLE}
2842     * @throws InterruptedException
2843     */
2844    protected void waitAndClickCloseWindow() throws InterruptedException {
2845        waitAndClickByXpath(CLOSE_WINDOW_XPATH_TITLE);
2846    }
2847
2848    /**
2849     * {@link #COPY_LINK_TEXT}
2850     * @throws InterruptedException
2851     */
2852    protected void waitAndClickCopy() throws InterruptedException {
2853        waitAndClickByLinkText(COPY_LINK_TEXT);
2854    }
2855
2856    protected void waitAndClickDemoLink() throws InterruptedException {
2857        jGrowl("Click Demo Link");
2858        waitAndClickById("Demo-DemoLink", "");
2859    }
2860
2861    /**
2862     * {}@link #DOC_SEARCH_XPATH}
2863     * @throws InterruptedException
2864     */
2865    protected void waitAndClickDocSearch() throws InterruptedException {
2866        waitAndClickByXpath(DOC_SEARCH_XPATH);
2867    }
2868
2869    /**
2870     * {@link #DOC_SEARCH_XPATH_TITLE}
2871     * @throws InterruptedException
2872     */
2873    protected void waitAndClickDocSearchTitle() throws InterruptedException {
2874        waitAndClickByXpath(DOC_SEARCH_XPATH_TITLE);
2875    }
2876
2877    protected void waitAndClickLibraryLink() throws InterruptedException {
2878        jGrowl("Click Library Link");
2879        waitAndClickById("Demo-LibraryLink", "");
2880    }
2881
2882    /**
2883     * {@link #LOGOUT_XPATH}
2884     * @throws InterruptedException
2885     */
2886    protected void waitAndClickLogout() throws InterruptedException {
2887        waitAndClickLogout(this);
2888    }
2889
2890    /**
2891     * {@link #LOGOUT_XPATH}
2892     * @param failable
2893     * @throws InterruptedException
2894     */
2895    protected void waitAndClickLogout(JiraAwareFailable failable) throws InterruptedException {
2896        jGrowl("Logging out");
2897        selectTopFrame();
2898        waitAndClickByXpath(LOGOUT_XPATH, failable);
2899    }
2900
2901    protected void waitAndClickMainMenu() throws InterruptedException {
2902        waitAndClickByLinkText(MAIN_MENU_LINK_TEXT, this);
2903    }
2904
2905    /**
2906     * {}@link #MAIN_MENU_LINK_TEXT}
2907     * @param failable
2908     * @throws InterruptedException
2909     */
2910    private void waitAndClickMainMenu(JiraAwareFailable failable) throws InterruptedException {
2911        waitAndClickByLinkText(MAIN_MENU_LINK_TEXT, failable);
2912    }
2913
2914    protected void waitAndClickRouteLogIcon() throws InterruptedException {
2915        jGrowl("Click Route Log link");
2916        waitAndClickByXpath("//img[@alt=\"Route Log for Document\"]");
2917    }
2918
2919    /**
2920     * {@link #SAVE_XPATH}
2921     * @throws InterruptedException
2922     */
2923    protected void waitAndClickSave() throws InterruptedException {
2924        waitAndClickByXpath(SAVE_XPATH);
2925    }
2926
2927    protected void waitAndClickSaveByText() throws InterruptedException {
2928        waitAndClickButtonByText("Save");
2929    }
2930
2931    /**
2932     * {@link #SUBMIT_XPATH}
2933     * @throws InterruptedException
2934     */
2935    protected void waitAndClickSubmit() throws InterruptedException {
2936        jGrowl("Click Submit");
2937        waitAndClickByXpath(SUBMIT_XPATH);
2938    }
2939
2940    protected void waitAndClickSubmitByText() throws InterruptedException {
2941        waitAndClickButtonByText("Submit");
2942    }
2943
2944    /**
2945     * {@link #APPROVE_XPATH}
2946     * @throws InterruptedException
2947     */
2948    protected void waitAndClickApprove() throws InterruptedException {
2949        jGrowl("Click Approve");
2950        waitAndClickByXpath(APPROVE_XPATH);
2951    }
2952
2953    protected void waitAndClickApproveByText() throws InterruptedException {
2954        waitAndClickButtonByText("Approve");
2955    }
2956
2957    /**
2958     * {@link #DISAPPROVE_XPATH}
2959     * @throws InterruptedException
2960     */
2961    protected void waitAndClickDisapprove() throws InterruptedException {
2962        jGrowl("Click Disapprove");
2963        waitAndClickByXpath(DISAPPROVE_XPATH);
2964    }
2965
2966    protected void waitAndClickDisapproveByText() throws InterruptedException {
2967        waitAndClickButtonByText("Disapprove");
2968    }
2969
2970    /**
2971     * {@link #ACKNOWLEDGE_XPATH}
2972     * @throws InterruptedException
2973     */
2974    protected void waitAndClickAcknowledge() throws InterruptedException {
2975        jGrowl("Click Acknowledge");
2976        waitAndClickByXpath(ACKNOWLEDGE_XPATH);
2977    }
2978
2979    protected void waitAndClickAcknowledgeByText() throws InterruptedException {
2980        waitAndClickButtonByText("Acknowledge");
2981    }
2982
2983    /**
2984     * {@link #CLOSE_XPATH}
2985     * @throws InterruptedException
2986     */
2987    protected void waitAndClickClose() throws InterruptedException {
2988        jGrowl("Click Close");
2989        waitAndClickByXpath(CLOSE_XPATH);
2990    }
2991
2992    protected void waitAndClickCloseByText() throws InterruptedException {
2993        waitAndClickButtonByText("Close");
2994    }
2995
2996    /**
2997     * {@link #XML_INGESTER_LINK_TEXT}
2998     * @param failable
2999     * @throws InterruptedException
3000     */
3001    protected void waitAndClickXMLIngester(JiraAwareFailable failable) throws InterruptedException {
3002        waitAndClickByLinkText(XML_INGESTER_LINK_TEXT, failable);
3003    }
3004
3005    protected void waitAndCreateNew() throws InterruptedException {
3006        waitAndCreateNew(this.getClass().toString());
3007    }
3008
3009    protected void waitAndCreateNew(String message) throws InterruptedException {
3010        selectFrameIframePortlet();
3011        jGrowl("Create New");
3012        waitAndClickCreateNew(message);
3013    }
3014
3015    /**
3016     * {@link #CREATE_NEW_XPATH}
3017     * @throws InterruptedException
3018     */
3019    protected void waitAndClickCreateNew() throws InterruptedException {
3020        waitAndClickCreateNew(this.getClass().toString());
3021    }
3022
3023    protected void waitAndClickCreateNew(String message) throws InterruptedException {
3024        jGrowl("Click Create New");
3025        if (WebDriverUtils.waitFors(driver, By.xpath(CREATE_NEW_XPATH)).size() > 0) {
3026            waitAndClickByXpath(CREATE_NEW_XPATH, message);
3027        } else {
3028            System.out.println("waitAndClickByXpath(" + CREATE_NEW_XPATH + ") wasn't found trying " + CREATE_NEW_XPATH2);
3029            waitAndClickByXpath(CREATE_NEW_XPATH2, message);
3030        }
3031    }
3032
3033    protected void waitAndClickEdit() throws InterruptedException {
3034        waitAndClickByLinkText(EDIT_LINK_TEXT);
3035    }
3036
3037    /**
3038     * {@link #SEARCH_XPATH}
3039     * @throws InterruptedException
3040     */
3041    protected void waitAndClickSearch() throws InterruptedException {
3042        jGrowl("Click Search");
3043        waitAndClickByXpath(SEARCH_XPATH);
3044    }
3045
3046    protected void waitAndClickSearch2() throws InterruptedException {
3047        jGrowl("Click Search");
3048        waitAndClickByXpath(SEARCH_XPATH_2);
3049    }
3050
3051    protected void waitAndClickSearchSecond() throws InterruptedException {
3052        jGrowl("Click Search");
3053        waitAndClickByXpath(SEARCH_SECOND);
3054    }
3055
3056    protected void waitAndClickSearchByText() throws InterruptedException {
3057        waitAndClickButtonByText("Search");
3058    }
3059
3060    protected String waitForAgendaDocId() throws InterruptedException {
3061        String docId = waitForElementPresentByXpath("//div[@data-label=\"Document Number\"]").getText();
3062        jGrowl("Document Number is " + docId);
3063        return docId;
3064    }
3065
3066    protected String waitForDocId() throws InterruptedException {
3067        checkForDocError();
3068        waitForElementPresentByXpath(DOC_ID_XPATH);
3069        String docId = findElement(By.xpath(DOC_ID_XPATH)).getText();
3070        jGrowl("Document Number is " + docId);
3071        return docId;
3072    }
3073
3074    protected String waitForDocIdKrad() throws InterruptedException {
3075        failOnErrorMessageItem();
3076        waitForElementPresentByXpath(DOC_ID_KRAD_XPATH);
3077        String docId = findElement(By.xpath(DOC_ID_KRAD_XPATH)).getText();
3078        jGrowl("Document Number is " + docId);
3079
3080        return docId;
3081    }
3082
3083    protected String waitForDocInitiator() throws InterruptedException {
3084        waitForElementPresentByXpath(DOC_INITIATOR_XPATH);
3085
3086        return findElement(By.xpath(DOC_INITIATOR_XPATH)).getText();
3087    }
3088
3089    protected String waitForDocStatus() throws InterruptedException {
3090        waitForElementPresentByXpath(DOC_STATUS_XPATH);
3091
3092        return findElement(By.xpath(DOC_STATUS_XPATH)).getText();
3093    }
3094
3095    protected void waitForTitleToEqualKualiPortalIndex() throws InterruptedException {
3096        waitForTitleToEqualKualiPortalIndex(this.getClass().toString());
3097    }
3098
3099    protected void waitForToolTipTextPresent(String tooltipText) throws InterruptedException {
3100        assertEquals("ToolTip text not as expected", tooltipText, waitForToolTipPresent().getText());
3101    }
3102
3103    protected WebElement waitForToolTipPresent() throws InterruptedException {
3104        waitForElementPresent(".popover.top.in");
3105        WebElement tooltip = findElement(By.cssSelector(".popover.top.in"));
3106        jGrowl("ToolTip " + tooltip.getText());
3107        return tooltip;
3108    }
3109
3110    protected void waitForTitleToEqualKualiPortalIndex(String message) throws InterruptedException {
3111        Thread.sleep(2000);
3112        // This started failing in CI....
3113        // boolean failed = false;
3114        //
3115        // for (int second = 0;; second++) {
3116        //     Thread.sleep(1000);
3117        //     if (second >= waitSeconds) failed = true;
3118        //     try { if (failed || ITUtil.KUALI_PORTAL_TITLE.equals(driver.getTitle())) break; } catch (Exception e) {}
3119        // }
3120
3121        // WebDriverUtils.checkForIncidentReport(driver, message); // after timeout to be sure page is loaded
3122        // if (failed) jiraAwareFail("timeout of " + waitSeconds + " seconds " + message);
3123    }
3124
3125    /**
3126     * {@link #KRAD_XPATH}
3127     * @throws InterruptedException
3128     */
3129    protected void waitAndClickKRAD() throws InterruptedException {
3130        waitAndClickByLinkText(KRAD_XPATH);
3131    }
3132
3133    /**
3134     * Does the test page use KRAD UIF?
3135     * Useful if trying to re-use a test for both a KNS and KRAD screens that have different paths to the elements.
3136     * @return
3137     */
3138    protected boolean isKrad(){
3139        return (AutomatedFunctionalTestUtils.REMOTE_UIF_KRAD.equalsIgnoreCase(getUiFramework()));
3140    }
3141
3142    /**
3143     * Determines whether KRAD or KNS UIF is used for this test.
3144     * Useful if trying to re-use a test for both a KNS and KRAD screens that have different paths to the elements.
3145     * @return
3146     */
3147    public String getUiFramework() {
3148        return uiFramework;
3149    }
3150
3151    /**
3152     * Sets which UIF is used by this test
3153     */
3154    public void setUiFramework(String uiFramework) {
3155        this.uiFramework = uiFramework;
3156    }
3157    
3158    /**
3159     * presses Enter Key by Name
3160     */
3161    public void pressEnterByName(String locator){
3162        pressEnter(By.name(locator));
3163    }
3164    
3165    /**
3166     * presses Enter Key by Xpath
3167     */
3168    public void pressEnterByXpath(String locator){
3169        pressEnter(By.xpath(locator));
3170    }
3171    
3172    /**
3173     * presses Enter Key
3174     */
3175    public void pressEnter(By by){
3176         findElement(by).sendKeys(Keys.ENTER);
3177    }
3178}