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