View Javadoc
1   /**
2    * Copyright 2005-2016 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.demo.travel.account;
17  
18  import org.junit.Ignore;
19  import org.kuali.rice.testtools.selenium.WebDriverLegacyITBase;
20  import org.openqa.selenium.By;
21  import org.apache.commons.lang.RandomStringUtils;
22  import org.junit.Test;
23  
24  /**
25   * @author Kuali Rice Team (rice.collab@kuali.org)
26   */
27  public class DemoTravelAccountMaintenanceEditAft extends WebDriverLegacyITBase {
28  
29      /**
30       * /kr-krad/maintenance?methodToCall=maintenanceEdit&number=a14&dataObjectClassName=org.kuali.rice.krad.demo.travel.dataobject.TravelAccount&hideReturnLink=true
31       */
32      public static final String BOOKMARK_URL = "/kr-krad/maintenance?methodToCall=maintenanceEdit&number=a14&dataObjectClassName=org.kuali.rice.krad.demo.travel.dataobject.TravelAccount&hideReturnLink=true";
33  
34      /**
35       * Description field
36       */
37      public static final String DESCRIPTION_FIELD = "document.documentHeader.documentDescription";
38  
39      /**
40       * Explanation field
41       */
42      public static final String EXPLANATION_FIELD = "document.documentHeader.explanation";
43  
44      /**
45       * Organization document number field
46       */
47      public static final String ORGANIZATION_DOCUMENT_NUMBER_FIELD = "document.documentHeader.organizationDocumentNumber";
48  
49      /**
50       * Travel sub account field
51       */
52      public static final String SUB_ACCOUNT_FIELD = "newCollectionLines['document.newMaintainableObject.dataObject.subAccounts'].subAccount";
53  
54      /**
55       * Travel sub account name field
56       */
57      public static final String SUB_ACCOUNT_NAME_FIELD = "newCollectionLines['document.newMaintainableObject.dataObject.subAccounts'].subAccountName";
58  
59      /**
60       * Subsidized percent
61       */
62      public static final String SUBSIDIZED_PERCENT_FIELD = "document.newMaintainableObject.dataObject.subsidizedPercent";
63  
64      /**
65       * Date created.
66       */
67      public static final String DATE_CREATED_FIELD = "document.newMaintainableObject.dataObject.createDate";
68  
69      /**
70       * Fiscal officer ID
71       */
72      public static final String FISCAL_OFFICER_ID_FIELD = "document.newMaintainableObject.dataObject.foId";
73  
74      @Override
75      public String getBookmarkUrl() {
76          return BOOKMARK_URL;
77      }
78  
79      protected void navigate() throws Exception {
80          waitAndClickDemoLink();
81          waitAndClickByLinkText("Travel Account Maintenance (Edit)");
82      }
83  
84      protected void testTravelAccountMaintenanceEdit() throws Exception {
85          waitAndTypeByName("document.documentHeader.documentDescription", "Travel Account Edit"+RandomStringUtils.randomAlphabetic(2));
86  
87          // Verify that adding a duplicate Sub Account is not allowed.
88          String subAccountDuplicate = "A";
89          waitAndTypeByName(SUB_ACCOUNT_FIELD, subAccountDuplicate);
90          waitAndTypeByName("newCollectionLines['document.newMaintainableObject.dataObject.subAccounts'].subAccountName", "Sub Account 1"+RandomStringUtils.randomAlphabetic(2));
91          waitAndClickButtonByText("Add");
92          waitForProgressAddingLine();
93          String errorMessage []={"Duplicate Sub Accounts (Travel Sub Account Number) are not allowed."};
94          assertTextPresent(errorMessage);
95  
96          // Verify that adding a duplicate Sub Account and Sub Account Name is not allowed.
97          clearTextByName(SUB_ACCOUNT_FIELD);
98          waitAndTypeByName(SUB_ACCOUNT_FIELD, subAccountDuplicate);
99          clearTextByName("newCollectionLines['document.newMaintainableObject.dataObject.subAccounts'].subAccountName");
100         waitAndTypeByName("newCollectionLines['document.newMaintainableObject.dataObject.subAccounts'].subAccountName", "Sub Account A");
101         waitAndClickButtonByText("Add");
102         waitForProgressAddingLine();
103         String errorMessage2 []={"Duplicate Sub Accounts (Travel Sub Account Number) are not allowed."};
104         assertTextPresent(errorMessage2);
105         
106         //Check for LookUp search
107         waitAndClickByXpath("//button[@class='btn btn-default uif-action icon-search']");
108         gotoLightBox();
109         waitAndClickSearchByText();
110         waitAndClickReturnValue();
111         waitAndClickByXpath("//a/span[contains(text(),'Ad Hoc Recipients')]");
112         waitAndClickByXpath("//div[@data-parent='Uif-AdHocPersonCollection']/div/div/button[@class='btn btn-default uif-action icon-search']");
113         gotoLightBox();
114         waitAndClickSearchByText();
115         waitAndClickReturnValue();
116         waitAndClickByXpath("//div[@data-parent='CollectionGroup_AdHocWorkgroup']/div/div/button[@class='btn btn-default uif-action icon-search']");
117         gotoLightBox();
118         waitAndClickSearchByText();
119         waitAndClickReturnValue();
120 
121         // Add a new sub account
122         String subAccount = "Z1" + RandomStringUtils.randomAlphabetic(2);
123         clearTextByName(SUB_ACCOUNT_FIELD);
124         waitAndTypeByName(SUB_ACCOUNT_FIELD, subAccount);
125         clearTextByName("newCollectionLines['document.newMaintainableObject.dataObject.subAccounts'].subAccountName");
126         waitAndTypeByName("newCollectionLines['document.newMaintainableObject.dataObject.subAccounts'].subAccountName", "Sub Account 1"+RandomStringUtils.randomAlphabetic(2));
127         waitForElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.number' and @value='a14']");
128         waitForElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.name' and @value='Travel Account 14']");
129         waitForElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.foId' and @value='fran']");
130         waitAndClickButtonByText("Add");
131         waitForProgressAddingLine();
132         waitForElementPresentByXpath("//a[contains(text(),subAccount)]");
133 
134         saveSuccessfully();
135 
136         assertTextPresent("SAVED");
137 
138         submitSuccessfully();
139 
140         waitAndClickButtonByText("Reload");
141         waitForProgressLoading();
142         checkForDocErrorKrad();
143         waitForTextPresent("Document was successfully reloaded.");
144         assertTextPresent("FINAL");
145     }
146 
147     protected void testTravelAccountMaintenanceEditBlanketApprove() throws Exception {
148         waitAndTypeByName("document.documentHeader.documentDescription", "Travel Account Edit"+RandomStringUtils.randomAlphabetic(2));
149         clearTextByName("document.newMaintainableObject.dataObject.subsidizedPercent");
150         waitAndTypeByName("document.newMaintainableObject.dataObject.subsidizedPercent", "42");
151         clickBlanketApproveAndEditDocAgain();
152 
153         if(!isElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.subsidizedPercent' and @value='42']")) {
154             jiraAwareFail("BlanketApprove was not successful. subsidizedPercent should be 42");
155         }
156         waitAndTypeByName("document.documentHeader.documentDescription", "Travel Account Edit" + RandomStringUtils.randomAlphabetic(2));
157         clearTextByName("document.newMaintainableObject.dataObject.subsidizedPercent");
158         waitAndClickBlanketApprove();
159         waitAndClickConfirmBlanketApproveOk();
160         // waitAndClickByXpath("/html/body/form/div/div[2]/main/div/section[1]/div/div/div[2]/button[2]");
161         acceptAlertIfPresent();
162 
163     }
164 
165     protected void testTravelAccountMaintenanceEditBlanketApproveAdHocComplete() throws Exception {
166         waitAndTypeByName("document.documentHeader.documentDescription", "Travel Account Edit" + RandomStringUtils.randomAlphabetic(2));
167 
168         //add add hoc user with complete action
169         waitAndClickByLinkText("Ad Hoc Recipients");
170         waitAndSelectByName("newCollectionLines['document.adHocRoutePersons'].actionRequested", "COMPLETE");
171         waitAndTypeByName("newCollectionLines['document.adHocRoutePersons'].id", "dev1");
172         waitAndClickById("Uif-AdHocPersonCollection_add");
173 
174         //verify blanket approve fails with correct message
175         waitAndClickBlanketApprove();
176         waitAndClickConfirmBlanketApproveOk();
177         waitForTextPresent("Blanket Approve cannot be performed when adhoc route for completion request is newly added");
178 
179         //remove add hoc user
180         waitAndClickById("Uif-AdHocPersonCollection_del_line0");
181 
182         //add add hoc group with complete action
183         waitAndSelectByName("newCollectionLines['document.adHocRouteWorkgroups'].actionRequested", "COMPLETE");
184         waitAndTypeByName("newCollectionLines['document.adHocRouteWorkgroups'].recipientName", "Kuali Developers");
185         waitAndClickById("CollectionGroup_AdHocWorkgroup_add");
186         waitAndClickBlanketApprove();
187 
188         //verify blanket approve fails with correct message
189         waitAndClickBlanketApprove();
190         waitAndClickConfirmBlanketApproveOk();
191         waitForTextPresent("Blanket Approve cannot be performed when adhoc route for completion request is newly added");
192     }
193 
194     protected void testTravelAccountMaintenanceEditXss() throws Exception {
195         waitAndTypeByName(DESCRIPTION_FIELD,"\"/><script>alert('!')</script>");
196         waitAndTypeByName(EXPLANATION_FIELD,"\"/><script>alert('!')</script>");
197         waitAndTypeByName(ORGANIZATION_DOCUMENT_NUMBER_FIELD,"\"/><script>alert('!')</script>");
198         waitAndTypeByName(SUB_ACCOUNT_FIELD,"blah");
199         waitAndTypeByName(SUB_ACCOUNT_NAME_FIELD,"\"/><script>alert('!')</script>");
200         waitAndTypeByName(SUBSIDIZED_PERCENT_FIELD,"\"/><script>alert('!')</script>");
201 //        waitAndTypeByName(DATE_CREATED_FIELD,"\"/><script>alert('!')</script>"); // no longer an input field
202 //        waitAndTypeByName(FISCAL_OFFICER_ID_FIELD,"\"/><script>alert('!')</script>");
203         waitAndClickSaveByText();
204         Thread.sleep(1000);
205         if(isAlertPresent())    {
206             fail("XSS vulnerability identified.");
207         }
208     }
209 
210     protected boolean isAlertPresent() {
211         try {
212             driver.switchTo().alert();
213             return true;
214         }   // try
215         catch (Exception Ex) {
216             return false;
217         }   // catch
218     }
219     
220     protected void testEditFiscalOfficer() throws Exception {
221         String currentFiscalOfficer = findElement(By.name("document.newMaintainableObject.dataObject.foId")).getAttribute("value");
222         String newFiscalOfficer = "fran";
223         if ("fran".equals(currentFiscalOfficer)) {
224             newFiscalOfficer = "eric";
225         }
226 
227         checkForRequiredFields();
228         changeFiscalOfficer(newFiscalOfficer);
229         
230         // change eric back to fran
231         changeFiscalOfficer(currentFiscalOfficer);
232     }
233     
234     protected void testSubAccountOperations() throws Exception {
235         waitForElementNotPresent(By.xpath("//button[contains(text(),'Delete')]"));
236         waitAndTypeLabeledInput("Travel Sub Account Number:", "A");
237         waitAndTypeLabeledInput("Sub Account Name:", "Sub Account A");
238         waitAndClickButtonByExactText("Add");
239         waitForTextPresent("Duplicate Sub Accounts (Travel Sub Account Number) are not allowed.");
240     }
241 
242     private void changeFiscalOfficer(String newUser) throws Exception {
243         waitAndTypeByName("document.documentHeader.documentDescription", "Edit Fiscal Officer to " + newUser + " "  + RandomStringUtils.randomAlphabetic(2));
244         clearTextByName("document.newMaintainableObject.dataObject.foId");
245         waitAndTypeByName("document.newMaintainableObject.dataObject.foId", newUser);
246         clickBlanketApproveAndEditDocAgain();
247 
248         if(!isElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.foId' and @value='" + newUser + "']")) {
249             jiraAwareFail("Fiscal Officer Not Changed to " + newUser);
250         }
251     }
252 
253     private void checkForRequiredFields() throws Exception{
254     	waitForElementPresentByXpath("//label[contains(text(),'Description')]/span[contains(text(),'*')]");
255     	waitForElementPresentByXpath("//label[contains(text(),'Travel Account Number:')]/span[contains(text(),'*')]");
256     	waitForElementPresentByXpath("//label[contains(text(),'Travel Account Name:')]/span[contains(text(),'*')]");
257     	waitForElementPresentByXpath("//label[contains(text(),'Travel Account Type Code:')]/span[contains(text(),'*')]");
258     	waitForElementPresentByXpath("//label[contains(text(),'Date Created:')]/span[contains(text(),'*')]");
259     	waitForElementPresentByXpath("//label[contains(text(),'Travel Sub Account Number:')]/span[contains(text(),'*')]");
260     	waitForElementPresentByXpath("//label[contains(text(),'Sub Account Name:')]/span[contains(text(),'*')]");
261         jGrowl("Verify required messages are displayed");
262         clearTextByName("document.newMaintainableObject.dataObject.name");
263         waitAndClickSubmitByText();
264         waitForElementPresentByXpath("//h3[@id='pageValidationHeader' and contains(text(),'This page has 2 errors')]");
265         waitForElementPresentByXpath("//ul[@id='pageValidationList']/li/a[contains(text(),'Document Overview: 1 error')]");
266         waitForElementPresentByXpath("//ul[@id='pageValidationList']/li/a[contains(text(),'Account Information: 1 error')]");
267         waitForElementPresentByXpath("//div[@class='uif-messageCount' and contains(text(),'  1 error')]");
268     	String requiredMessage []={"Description: Required","Travel Account Name: Required"};
269     	assertTextPresent(requiredMessage);
270         waitAndClickSaveByText();
271     	assertTextPresent(requiredMessage);
272         waitAndClickBlanketApprove();
273     	assertTextPresent(requiredMessage);
274     	waitForElementPresentByXpath("//div[@data-label='Date Created']");
275     	waitAndTypeByName("document.newMaintainableObject.dataObject.name","Travel Account 14");
276     }
277 
278     private void clickBlanketApproveAndEditDocAgain() throws Exception{
279         waitAndClickBlanketApprove();
280 
281         //click on confirmation message
282         waitAndClickConfirmBlanketApproveOk();
283         acceptAlertIfPresent();
284         waitForProgressLoading();
285         checkForDocErrorKrad();
286 
287         // Redirected to Home page after Blanket Approve https://jira.kuali.org/browse/KULRICE-13042
288         waitAndClickDemoLink();
289         acceptAlertIfPresent();
290         waitAndClickByLinkText("Travel Account Maintenance (Edit)");
291     }
292 
293     @Test
294     public void testDemoTravelAccountMaintenanceEditBookmark() throws Exception {
295         testTravelAccountMaintenanceEdit();
296         passed();
297     }
298 
299     @Test
300     public void testDemoTravelAccountMaintenanceEditNav() throws Exception {
301         testTravelAccountMaintenanceEdit();
302         passed();
303     }
304 
305     @Test
306     public void testDemoTravelAccountMaintenanceEditBlanketApproveBookmark() throws Exception {
307         testTravelAccountMaintenanceEditBlanketApprove();
308         passed();
309     }
310 
311     @Test
312     public void testDemoTravelAccountMaintenanceEditBlanketApproveNav() throws Exception {
313         testTravelAccountMaintenanceEditBlanketApprove();
314         passed();
315     }
316 
317     @Test
318     public void testDemoTravelAccountMaintenanceEditXssBookmark() throws Exception {
319         testTravelAccountMaintenanceEditXss();
320         passed();
321     }
322 
323     @Test
324     public void testDemoTravelAccountMaintenanceEditXssNav() throws Exception {
325         testTravelAccountMaintenanceEditXss();
326         passed();
327     }
328 
329     @Test
330     public void testDemoTravelAccountMaintenanceEditFiscalOfficerBookmark() throws Exception {
331     	testEditFiscalOfficer();
332         passed();
333     }
334 
335     @Test
336     public void testDemoTravelAccountMaintenanceEditFiscalOfficerNav() throws Exception {
337         testEditFiscalOfficer();
338         passed();
339     }
340 
341     @Test
342     public void testDemoTravelAccountMaintenanceSubAccountOperationsBookmark() throws Exception {
343     	testSubAccountOperations();
344         passed();
345     }
346 
347     @Test
348     public void testDemoTravelAccountMaintenanceSubAccountOperationsNav() throws Exception {
349         testSubAccountOperations();
350         passed();
351     }
352 
353     @Ignore ("https://jira.kuali.org/browse/KULRICE-13357 AFT Failures Dialogs on CI")
354     @Test
355     public void testTravelAccountMaintenanceEditBlanketApproveAdHocCompleteBookmark() throws Exception {
356         testTravelAccountMaintenanceEditBlanketApproveAdHocComplete();
357         passed();
358     }
359 
360     @Ignore ("https://jira.kuali.org/browse/KULRICE-13357 AFT Failures Dialogs on CI")
361     @Test
362     public void testTravelAccountMaintenanceEditBlanketApproveAdHocCompleteNav() throws Exception {
363         testTravelAccountMaintenanceEditBlanketApproveAdHocComplete();
364         passed();
365     }
366 }