001    /*
002     * Copyright 2006-2012 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     */
016    package edu.samplu.travel.krad.test;
017    
018    import com.thoughtworks.selenium.DefaultSelenium;
019    import com.thoughtworks.selenium.Selenium;
020    import org.apache.commons.logging.LogFactory;
021    import org.apache.commons.logging.Log;
022    import org.junit.After;
023    import org.junit.Before;
024    import org.junit.Ignore;
025    import org.junit.Test;
026    import org.kuali.rice.krad.uif.UifConstants;
027    
028    import java.util.HashMap;
029    import java.util.Map;
030    
031    import static org.junit.Assert.assertEquals;
032    import static org.junit.Assert.assertNotNull;
033    import static org.junit.Assert.assertTrue;
034    
035    /**
036     *  Tests that the data attributes are rendered as expected for all controls
037     * 
038     * @author Kuali Rice Team (rice.collab@kuali.org)
039     */
040    public class UifDataAttributesIT {
041        private Selenium selenium;
042        private  Log log = LogFactory.getLog(getClass());
043    
044        @Before
045        public void setUp() throws Exception {
046            selenium = new DefaultSelenium("localhost", 4444, "*firefox", System.getProperty("remote.public.url"));
047            selenium.start();
048        }
049    
050        /**
051         * verify that a tag has simple data attributes
052         *
053         * @param tag - html tag e.g. img or a
054         * @param tagId - derived from the bean id set in the view
055         * @param tagIdSuffix - where applicable, a suffix that is appended to the control by krad e.g. _control
056         */
057        private void verifySimpleAttributes(String tag, String tagId, String tagIdSuffix) {
058            // test the attributes that are set via the data attributes list
059            tagId = tagId + tagIdSuffix;
060            String simpleAttributesXpath="//" + tag + "[(@id='" + tagId + "') and (@data-iconTemplateName='cool-icon-%s.png') and (@data-transitions='3')]";
061            assertTrue(tagId + " does not have simple data attributes (via list) present", selenium.isElementPresent(simpleAttributesXpath));
062            verifyStaticDataAttributes(tag, tagId);
063    
064        }
065    
066        /**
067         * test the attributes that are set via the data*Attribute properties
068         *
069         * @param tag - html tag e.g. img or a
070         * @param tagId - the html tag id - a combination of bean id and any suffix
071         */
072        private void verifyStaticDataAttributes(String tag, String tagId) {
073            final String simpleAttributesXpath;
074            simpleAttributesXpath="//" + tag + "[(@id='" + tagId + "')"
075                    + " and (@data-role='role') and (@data-type='type') and (@data-meta='meta')]";
076            assertTrue(tagId + " does not have simple data attributes (via data*Attribute) properties present",
077                    selenium.isElementPresent(simpleAttributesXpath));
078        }
079    
080        /**
081         * check that complex attributes exist in the script
082         *
083         * @param tagId - the expected tag id
084         * @param suffix - the expected suffix e.g. _button
085         */
086        private void verifyComplexAttributes(String tagId, String suffix) {
087            tagId = tagId + suffix;
088            String complexAttributesXpath="//input[(@type='hidden') and (@data-role='dataScript') and (@data-for='"+ tagId +  "')]";
089            assertTrue(tagId + ": complex data attributes script not found", selenium.isElementPresent(complexAttributesXpath));
090    
091            // the message field does not support complex attributes
092            //if (!tagId.equalsIgnoreCase("messageField")) {
093                String scriptValue = selenium.getAttribute(complexAttributesXpath + "@value");
094                assertNotNull("script value is null",scriptValue);
095            boolean ok = scriptValue.contains(
096                    "jQuery('#" + tagId + "').data('capitals', {kenya:'nairobi', uganda:'kampala', tanzania:'dar'});")
097                    && scriptValue.contains("jQuery('#" + tagId + "').data('intervals', {short:2, medium:5, long:13});");
098            if (!ok) {
099                log.info("scriptValue for " + tagId + " is " + scriptValue);
100            }
101            // check for complex attributes
102            assertTrue(tagId + ": complex attributes script does not contain expected code", ok);
103            //}
104        }
105    
106        /**
107         * check that all attributes exist in the script
108         *
109         * @param tagId - the expected tag id
110         * @param suffix - the expected suffix e.g. _control
111         * @return true if all attributes were found in script, false otherwise
112         */
113        private boolean verifyAllAttributesInScript(String tagId, String suffix) {
114            tagId = tagId + suffix;
115            String complexAttributesXpath="//input[(@type='hidden') and (@data-for='"+ tagId +  "')]";
116            assertTrue(tagId + ": complex data attributes script not found", selenium.isElementPresent(complexAttributesXpath));
117    
118            // the message field does not support complex attributes
119            String scriptValue = selenium.getAttribute(complexAttributesXpath + "@value");
120            assertNotNull("script value is null",scriptValue);
121            // log.info("scriptValue for " + tagId + " is " + scriptValue);
122            return scriptValue.contains("jQuery('#" + tagId + "').data('transitions', 3);") &&
123                    scriptValue.contains("jQuery('#" + tagId + "').data('iconTemplateName', 'cool-icon-%s.png');") &&
124                    scriptValue.contains("jQuery('#" + tagId + "').data('capitals', {kenya:'nairobi', uganda:'kampala', tanzania:'dar'});") &&
125                    scriptValue.contains("jQuery('#" + tagId + "').data('intervals', {short:2, medium:5, long:13});");
126        }
127    
128    
129        /**
130         * Tests that the data attributes are rendered as expected for all controls
131         */
132        @Test
133        public void testDataAttributesPresentInControls () {
134            selenium.open(System.getProperty("remote.public.url"));
135            assertEquals("Login", selenium.getTitle());
136            selenium.type("__login_user", "admin");
137            selenium.click("//input[@value='Login']");
138            selenium.waitForPageToLoad("50000");
139            assertEquals("Kuali Portal Index", selenium.getTitle());
140            selenium.open(
141                    "/kr-dev/kr-krad/data-attributes-test-uif-controller?viewId=dataAttributesView_selenium&methodToCall=start");
142            selenium.waitForPageToLoad("50000");
143    
144            // custom suffix to mark  test bean ids
145            String testIdSuffix = "_attrs";
146            // input fields, whose controls are implemented as spring form tags, will have both simple and complex attributes set via a script
147            String[] inputControls = {"textInputField", "textAreaInputField", "dropDown", "datePicker", "fileUpload", "userControl",
148                    "spinnerControl", "hiddenControl", "checkBox"};//, "radioButton",
149            for (int i=0; i<inputControls.length; i++) {
150                assertTrue(inputControls[i] + ": script does not contain expected code",
151                        verifyAllAttributesInScript(inputControls[i], testIdSuffix + UifConstants.IdSuffixes.CONTROL));
152                String tag = "input";
153                if (inputControls[i].equalsIgnoreCase("textAreaInputField")) {
154                    tag = "textarea";
155                } else if (inputControls[i].equalsIgnoreCase("dropDown")) {
156                    tag = "select";
157                }
158                verifyStaticDataAttributes(tag, inputControls[i] + testIdSuffix + UifConstants.IdSuffixes.CONTROL);
159            }
160            // these controls allow for simple attributes on the tag and complex attributes via js
161            Map<String, String[]> otherControlsMap = new HashMap<String, String[]>();
162            // controls whose simple attributes are set in an img tag
163            String[] imgControls = {"imageField_image"};
164            // fields whose simple attributes are set in an anchor tag
165            String[] anchorFields = {"navigationLink", "actionLink-noImage", "actionLink-imageRight", "actionLink-imageLeft",
166                    "linkField", "linkElement"};
167            // fields whose simple attributes are set in a span tag
168            String[] spanFields = {"messageField", "spaceField"};
169            // fields whose simple attributes are set in an input tag
170            String[] inputFields = {"imageAction"};
171            // fields whose simple attributes are set in button tag
172            String[] buttonElements = {"buttonTextOnly", "buttonImageBottom", "buttonImageLeft", "buttonImageTop", "buttonImageRight"};
173            // iframe field
174            String[] iframeField = {"iframe"};
175            
176            otherControlsMap.put("img", imgControls);
177            otherControlsMap.put("a", anchorFields);
178            otherControlsMap.put("span", spanFields);
179            otherControlsMap.put("input", inputFields);
180            otherControlsMap.put("button", buttonElements);
181            otherControlsMap.put("iframe", iframeField);
182    
183            // a map to hold the tags where the simple attributes are affixed
184            // if a tag is not here, a empty string will be used for the suffix
185            Map<String, String> simpleTagIdSuffix = new HashMap<String, String>();
186            simpleTagIdSuffix.put("span", "_span");
187            
188    
189            for (String tag: otherControlsMap.keySet()) {
190                String[] controlIds = otherControlsMap.get(tag);
191                for (int i=0; i<controlIds.length; i++) {
192                    String tagId = controlIds[i];
193    
194                    // check for complex attributes
195                    verifyComplexAttributes(tagId, testIdSuffix);
196    
197                    // determine whether we are using a tag id suffix for the simple attributes
198                    String tagIdSuffix = testIdSuffix;
199                    if (simpleTagIdSuffix.containsKey(tag)) {
200                        tagIdSuffix = tagIdSuffix + simpleTagIdSuffix.get(tag);
201                    }
202    
203                    // check for simple attributes
204                    verifySimpleAttributes(tag, tagId, tagIdSuffix);
205                }
206                
207                // test label field - which uses the tagId suffix for both the simple attributes and complex
208                String tagId = "textInputField";
209                String tagIdSuffix = testIdSuffix + "_label";
210                // check for complex attributes
211                verifyComplexAttributes(tagId, tagIdSuffix);
212                // check for simple attributes
213                verifySimpleAttributes("label", tagId, tagIdSuffix);
214    
215                //test that the radio buttons have the 3 data attributes that can appear in the tag
216                tagId = "radioButton" + testIdSuffix + UifConstants.IdSuffixes.CONTROL;
217                String[] radioButtonIds = {tagId + "1", tagId + "2"};
218                for (String id: radioButtonIds) {
219                    verifyStaticDataAttributes("input", id);
220                }
221                //test that all complex and simple attributes set via the list are in a script
222                verifyAllAttributesInScript(tagId, "");
223            }
224        }
225    
226        @After
227        public void tearDown() throws Exception {
228            selenium.stop();
229        }
230    }