001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.test.jsf;
042:
043: import java.awt.Container;
044: import java.awt.event.KeyEvent;
045: import java.io.IOException;
046: import org.netbeans.jellytools.JellyTestCase;
047: import org.netbeans.jellytools.NbDialogOperator;
048: import org.netbeans.jellytools.NewFileWizardOperator;
049: import org.netbeans.jellytools.NewProjectWizardOperator;
050: import org.netbeans.jellytools.Bundle;
051: import org.netbeans.jellytools.EditorOperator;
052: import org.netbeans.jellytools.NewWebProjectNameLocationStepOperator;
053: import org.netbeans.jellytools.ProjectsTabOperator;
054: import org.netbeans.jellytools.TopComponentOperator;
055: import org.netbeans.jellytools.actions.ActionNoBlock;
056: import org.netbeans.jellytools.actions.Action;
057: import org.netbeans.jellytools.actions.EditAction;
058: import org.netbeans.jellytools.actions.OpenAction;
059: import org.netbeans.jellytools.modules.form.ComponentPaletteOperator;
060: import org.netbeans.jellytools.modules.web.nodes.WebPagesNode;
061: import org.netbeans.jemmy.operators.JTableOperator;
062: import org.netbeans.jellytools.nodes.Node;
063: import org.netbeans.jellytools.nodes.SourcePackagesNode;
064: import org.netbeans.jemmy.ComponentSearcher;
065: import org.netbeans.jemmy.operators.JButtonOperator;
066: import org.netbeans.jemmy.operators.JCheckBoxOperator;
067: import org.netbeans.jemmy.operators.JListOperator;
068: import org.netbeans.jemmy.operators.JToggleButtonOperator;
069: import org.netbeans.jemmy.operators.JTreeOperator;
070: import org.netbeans.jemmy.operators.Operator.DefaultStringComparator;
071: import org.netbeans.junit.NbTestSuite;
072: import org.netbeans.junit.ide.ProjectSupport;
073:
074: /** Test JSF support.
075: *
076: * @author Lukasz Grela
077: * @author Jiri Skrivanek
078: */
079: public class JsfFunctionalTest extends JellyTestCase {
080:
081: public static final String PROJECT_NAME = "myjsfproject";
082: public static final String WELCOME_JSP = "welcomeJSF.jsp";
083: public static final String INDEX_JSP = "index.jsp";
084: public static final String FROM_ACTION1 = "FromAction1";
085: public static final String FROM_ACTION2 = "FromAction2";
086: public static final String FROM_OUTCOME1 = "FromOutcome1";
087: public static final String FROM_OUTCOME2 = "FromOutcome2";
088: public static final String DESCRIPTION_BEAN = "DescriptionBean";
089: public static final String DESCRIPTION_RULE = "DescriptionRule";
090: public static final String DESCRIPTION_CASE1 = "DescriptionCase1";
091: public static final String DESCRIPTION_CASE2 = "DescriptionCase2";
092:
093: public JsfFunctionalTest(String name) {
094: super (name);
095: }
096:
097: public static NbTestSuite suite() {
098: NbTestSuite suite = new NbTestSuite();
099: suite.addTest(new JsfFunctionalTest(
100: "testCreateWebProjectWithJSF"));
101: suite.addTest(new JsfFunctionalTest("testManagedBeanWizard"));
102: suite.addTest(new JsfFunctionalTest("testManagedBeanDelete"));
103: suite.addTest(new JsfFunctionalTest("testAddManagedBean"));
104: suite.addTest(new JsfFunctionalTest("testAddNavigationRule"));
105: suite.addTest(new JsfFunctionalTest("testAddNavigationCase"));
106: suite.addTest(new JsfFunctionalTest(
107: "testAddNavigationCaseWithNewRule"));
108: suite.addTest(new JsfFunctionalTest("testAddJSFToProject"));
109: suite.addTest(new JsfFunctionalTest("testJSFPalette"));
110: return suite;
111: }
112:
113: @Override
114: public void setUp() {
115: System.out.println("### " + getName() + " ###");
116: }
117:
118: /** Use for internal test execution inside IDE
119: * @param args command line arguments
120: */
121: public static void main(java.lang.String[] args) {
122: junit.textui.TestRunner.run(suite());
123: }
124:
125: public void testCreateWebProjectWithJSF() throws IOException {
126: // "Web"
127: String web = Bundle.getStringTrimmed(
128: "org.netbeans.modules.web.core.Bundle",
129: "OpenIDE-Module-Display-Category");
130: // "Web Application"
131: String webApplication = Bundle.getStringTrimmed(
132: "org.netbeans.modules.web.project.ui.wizards.Bundle",
133: "Templates/Project/Web/emptyWeb.xml");
134: NewProjectWizardOperator nop = NewProjectWizardOperator
135: .invoke();
136: nop.selectCategory(web);
137: nop.selectProject(webApplication);
138: nop.next();
139: NewWebProjectNameLocationStepOperator lop = new NewWebProjectNameLocationStepOperator();
140: lop.setProjectName(PROJECT_NAME);
141: lop.setProjectLocation(getDataDir().getCanonicalPath());
142: lop.next();
143: lop.next();
144: NewProjectWizardOperator frameworkStep = new NewProjectWizardOperator();
145: // select JavaServer Faces
146: JTableOperator tableOper = new JTableOperator(frameworkStep);
147: boolean found = false;
148: for (int i = 0; i < tableOper.getRowCount(); i++) {
149: if (tableOper
150: .getValueAt(i, 1)
151: .toString()
152: .startsWith(
153: "org.netbeans.modules.web.jsf.JSFFrameworkProvider")) { // NOI18N
154: tableOper.selectCell(i, 0);
155: found = true;
156: break;
157: }
158: }
159: assertTrue("JavaServer Faces framework not found.", found);
160: frameworkStep.finish();
161: ProjectSupport.waitScanFinished();
162: // Check project contains all needed files.
163: WebPagesNode webPages = new WebPagesNode(PROJECT_NAME);
164: Node welcomeJSF = new Node(webPages, "welcomeJSF.jsp");
165: new OpenAction().perform(welcomeJSF);
166: new EditorOperator("welcomeJSF.jsp").close();
167: Node facesconfig = new Node(webPages,
168: "WEB-INF|faces-config.xml");
169: new OpenAction().perform(facesconfig);
170: // open faces-config.xml is used in next test cases
171: getFacesConfig();
172: }
173:
174: /** Test JSF Managed Bean Wizard. */
175: public void testManagedBeanWizard() {
176: NewFileWizardOperator projectWizard = NewFileWizardOperator
177: .invoke();
178: // "Java Server Faces"
179: String category = Bundle.getStringTrimmed(
180: "org/netbeans/modules/web/jsf/resources/Bundle",
181: "Templates/JSF");
182: // "JSF Managed Bean"
183: String filetype = Bundle.getStringTrimmed(
184: "org/netbeans/modules/web/jsf/resources/Bundle",
185: "Templates/JSF/JSFManagedBean.java");
186: projectWizard.selectCategory(category);
187: projectWizard.selectFileType(filetype);
188: projectWizard.next();
189: NewJSFBeanStepOperator bean = new NewJSFBeanStepOperator();
190: bean.setClassName("MyManagedBean");
191: bean.selectScope("session");
192: bean.cboPackage().getTextField().setText("mypackage");
193: bean.finish();
194: // verify
195: new EditorOperator("MyManagedBean.java").close();
196: EditorOperator facesEditor = getFacesConfig();
197: String expected = "<managed-bean>";
198: assertTrue("faces-config.xml should contain " + expected,
199: facesEditor.contains(expected));
200: expected = "<managed-bean-name>MyManagedBean</managed-bean-name>";
201: assertTrue("faces-config.xml should contain " + expected,
202: facesEditor.contains(expected));
203: expected = "<managed-bean-class>mypackage.MyManagedBean</managed-bean-class>";
204: assertTrue("faces-config.xml should contain " + expected,
205: facesEditor.contains(expected));
206: expected = "<managed-bean-scope>session</managed-bean-scope>";
207: assertTrue("faces-config.xml should contain " + expected,
208: facesEditor.contains(expected));
209: }
210:
211: /** Test that delete safely bean removes record from faces-config.xml. */
212: public void testManagedBeanDelete() {
213: Node node = new Node(new SourcePackagesNode(PROJECT_NAME),
214: "mypackage|MyManagedBean.java");
215: new ActionNoBlock(null, "Refactor|Safe Delete...")
216: .perform(node);
217: NbDialogOperator safeDeleteDialog = new NbDialogOperator(
218: "Safe Delete");
219: new JButtonOperator(safeDeleteDialog, "Refactor").push();
220: node.waitNotPresent();
221: // verify
222: EditorOperator facesEditor = getFacesConfig();
223: String expected = "<managed-bean>";
224: assertFalse("faces-config.xml should not contain " + expected,
225: facesEditor.contains(expected));
226: }
227:
228: /** Test adding JSF Managed Bean from faces-config.xml. */
229: public void testAddManagedBean() {
230: EditorOperator editor = getFacesConfig();
231: Action addBeanAction = new ActionNoBlock(null,
232: "JavaServer Faces|Add Managed Bean...");
233: addBeanAction.perform(editor);
234: AddManagedBeanOperator addBeanOper = new AddManagedBeanOperator();
235: addBeanOper.setBeanName("SecondBean");
236: addBeanOper.setBeanClass("mypackage.MyManagedBean");
237: addBeanOper.selectScope("application");
238: addBeanOper.setBeanDescription(DESCRIPTION_BEAN);
239: addBeanOper.add();
240: // verify
241: EditorOperator facesEditor = getFacesConfig();
242: String expected = "<managed-bean>";
243: assertTrue("faces-config.xml should contain " + expected,
244: facesEditor.contains(expected));
245: expected = "<managed-bean-name>SecondBean</managed-bean-name>";
246: assertTrue("faces-config.xml should contain " + expected,
247: facesEditor.contains(expected));
248: expected = "<managed-bean-class>mypackage.MyManagedBean</managed-bean-class>";
249: assertTrue("faces-config.xml should contain " + expected,
250: facesEditor.contains(expected));
251: expected = "<managed-bean-scope>application</managed-bean-scope>";
252: assertTrue("faces-config.xml should contain " + expected,
253: facesEditor.contains(expected));
254: }
255:
256: /** Test adding navigation rule from faces-config.xml. */
257: public void testAddNavigationRule() throws IOException {
258: EditorOperator editor = getFacesConfig();
259: Action addRule = new ActionNoBlock(null,
260: "JavaServer Faces|Add Navigation Rule...");
261: addRule.perform(editor);
262: AddNavigationRuleDialogOperator rule = new AddNavigationRuleDialogOperator();
263: rule.setRuleFromView("/" + WELCOME_JSP);
264: rule.setRuleDescription(DESCRIPTION_RULE);
265: rule.add();
266: editor.waitModified(true);
267: editor.save();
268: // verify
269: String expected = "<from-view-id>/welcomeJSF.jsp</from-view-id>";
270: assertTrue("faces-config.xml should contain " + expected,
271: editor.contains(expected));
272: expected = "<navigation-rule>";
273: assertTrue("faces-config.xml should contain " + expected,
274: editor.contains(expected));
275: expected = "</navigation-rule>";
276: assertTrue("faces-config.xml should contain " + expected,
277: editor.contains(expected));
278: expected = DESCRIPTION_RULE;
279: assertTrue("faces-config.xml should contain " + expected,
280: editor.contains(expected));
281: }
282:
283: /** Test adding navigation case from faces-config.xml. */
284: public void testAddNavigationCase() throws IOException {
285: EditorOperator editor = getFacesConfig();
286: Action addCase = new ActionNoBlock(null,
287: "JavaServer Faces|Add Navigation Case...");
288: addCase.perform(editor);
289: AddNavigationCaseDialogOperator caseOper = new AddNavigationCaseDialogOperator();
290: caseOper.selectFromView("/" + WELCOME_JSP);
291: caseOper.selectToView("/" + WELCOME_JSP);
292: caseOper.setFromAction(FROM_ACTION1);
293: caseOper.setFromOutcome(FROM_OUTCOME1);
294: caseOper.setRuleDescription(DESCRIPTION_CASE1);
295: caseOper.add();
296: editor.waitModified(true);
297: editor.save();
298: // verify
299: String expected = "<from-action>" + FROM_ACTION1
300: + "</from-action>";
301: assertTrue("faces-config.xml should contain " + expected,
302: editor.contains(expected));
303: expected = "<from-outcome>" + FROM_OUTCOME1 + "</from-outcome>";
304: assertTrue("faces-config.xml should contain " + expected,
305: editor.contains(expected));
306: expected = "<to-view-id>/" + WELCOME_JSP + "</to-view-id>";
307: assertTrue("faces-config.xml should contain " + expected,
308: editor.contains(expected));
309: expected = "<navigation-case>";
310: assertTrue("faces-config.xml should contain " + expected,
311: editor.contains(expected));
312: expected = "</navigation-case>";
313: assertTrue("faces-config.xml should contain " + expected,
314: editor.contains(expected));
315: expected = DESCRIPTION_CASE1;
316: assertTrue("faces-config.xml should contain " + expected,
317: editor.contains(expected));
318: }
319:
320: /** Test adding navigation case with new rule from faces-config.xml. */
321: public void testAddNavigationCaseWithNewRule() throws IOException {
322: EditorOperator editor = getFacesConfig();
323: Action addCase = new ActionNoBlock(null,
324: "JavaServer Faces|Add Navigation Case...");
325: addCase.perform(editor);
326: AddNavigationCaseDialogOperator caseOper = new AddNavigationCaseDialogOperator();
327: caseOper.cboFromView().getTextField().setText("/" + INDEX_JSP);
328: caseOper.setFromAction(FROM_ACTION2);
329: caseOper.setFromOutcome(FROM_OUTCOME2);
330: caseOper.setRuleDescription(DESCRIPTION_CASE2);
331: caseOper.checkRedirect(true);
332: caseOper.cboToView().getTextField().setText("/" + INDEX_JSP);
333: caseOper.add();
334: editor.waitModified(true);
335: editor.save();
336: // verify
337: String expected = "<from-view-id>/" + INDEX_JSP
338: + "</from-view-id>";
339: assertTrue("faces-config.xml should contain " + expected,
340: editor.contains(expected));
341: expected = "<from-action>" + FROM_ACTION2 + "</from-action>";
342: assertTrue("faces-config.xml should contain " + expected,
343: editor.contains(expected));
344: expected = "<from-outcome>" + FROM_OUTCOME2 + "</from-outcome>";
345: assertTrue("faces-config.xml should contain " + expected,
346: editor.contains(expected));
347: expected = "<to-view-id>/" + INDEX_JSP + "</to-view-id>";
348: assertTrue("faces-config.xml should contain " + expected,
349: editor.contains(expected));
350: expected = "<redirect/>";
351: assertTrue("faces-config.xml should contain " + expected,
352: editor.contains(expected));
353: expected = DESCRIPTION_CASE2;
354: assertTrue("faces-config.xml should contain " + expected,
355: editor.contains(expected));
356: }
357:
358: /** Test adding JSF framework to existing web application. */
359: public void testAddJSFToProject() throws IOException {
360: // "Web"
361: String web = Bundle.getStringTrimmed(
362: "org.netbeans.modules.web.core.Bundle",
363: "OpenIDE-Module-Display-Category");
364: // "Web Application"
365: String webApplication = Bundle.getStringTrimmed(
366: "org.netbeans.modules.web.project.ui.wizards.Bundle",
367: "Templates/Project/Web/emptyWeb.xml");
368: NewProjectWizardOperator nop = NewProjectWizardOperator
369: .invoke();
370: nop.selectCategory(web);
371: nop.selectProject(webApplication);
372: nop.next();
373: NewWebProjectNameLocationStepOperator lop = new NewWebProjectNameLocationStepOperator();
374: lop.setProjectName(PROJECT_NAME + "2");
375: lop.setProjectLocation(getDataDir().getCanonicalPath());
376: lop.next();
377: lop.finish();
378:
379: // add JSF framework using project properties
380: // open project properties
381: ProjectsTabOperator.invoke().getProjectRootNode(
382: PROJECT_NAME + "2").properties();
383: // "Project Properties"
384: String projectPropertiesTitle = Bundle
385: .getStringTrimmed(
386: "org.netbeans.modules.web.project.ui.customizer.Bundle",
387: "LBL_Customizer_Title");
388: NbDialogOperator propertiesDialogOper = new NbDialogOperator(
389: projectPropertiesTitle);
390: // select "Frameworks" category
391: new Node(new JTreeOperator(propertiesDialogOper), "Frameworks")
392: .select();
393: new JButtonOperator(propertiesDialogOper, "Add").pushNoBlock();
394: NbDialogOperator addFrameworkOper = new NbDialogOperator(
395: "Add a Framework");
396: // select "JavaServer Faces" but item is instance of org.netbeans.modules.web.jsf.JSFFrameworkProvider which we need to select
397: new JListOperator(addFrameworkOper)
398: .selectItem("org.netbeans.modules.web.jsf.JSFFrameworkProvider");
399: addFrameworkOper.ok();
400: new JCheckBoxOperator(propertiesDialogOper, "Validate XML")
401: .setSelected(false);
402: new JCheckBoxOperator(propertiesDialogOper, "Verify Objects")
403: .setSelected(true);
404: // confirm properties dialog
405: propertiesDialogOper.ok();
406:
407: // Check project contains all needed files.
408: WebPagesNode webPages = new WebPagesNode(PROJECT_NAME + "2");
409: Node welcomeJSF = new Node(webPages, "welcomeJSF.jsp");
410: Node facesconfig = new Node(webPages,
411: "WEB-INF|faces-config.xml");
412: webPages.setComparator(new DefaultStringComparator(true, true));
413: Node webXML = new Node(webPages, "WEB-INF|web.xml");
414: new EditAction().performAPI(webXML);
415: EditorOperator webXMLEditor = new EditorOperator("web.xml");
416: webXMLEditor.select("validateXml");
417: assertTrue("Validate XML should be false.", webXMLEditor
418: .getText(webXMLEditor.getLineNumber() + 1).indexOf(
419: "false") > -1);
420: webXMLEditor.select("verifyObjects");
421: assertTrue("Verify Objects should be true.", webXMLEditor
422: .getText(webXMLEditor.getLineNumber() + 1).indexOf(
423: "true") > -1);
424: webXMLEditor.close();
425: }
426:
427: /** Test JSF Palette. */
428: public void testJSFPalette() {
429: EditorOperator editorOper = new EditorOperator(INDEX_JSP);
430: ComponentPaletteOperator paletteOper = new ComponentPaletteOperator();
431: // collapse HTML category
432: JCheckBoxOperator htmlCategoryOper = new JCheckBoxOperator(
433: paletteOper, "HTML");
434: if (htmlCategoryOper.isSelected()) {
435: htmlCategoryOper.push();
436: }
437: // expand JSF category
438: JCheckBoxOperator jsfCategoryOper = new JCheckBoxOperator(
439: paletteOper, "JSF");
440: if (!jsfCategoryOper.isSelected()) {
441: jsfCategoryOper.push();
442: }
443: editorOper.makeComponentVisible();
444: paletteOper.selectComponent("JSF Form");
445: paletteOper.pushKey(KeyEvent.VK_ENTER);
446: new NbDialogOperator("Insert JSF Form").ok();
447: String expected = "<f:view>";
448: assertTrue("index.jsp should contain " + expected + ".",
449: editorOper.contains(expected));
450: expected = "<h:form>";
451: assertTrue("index.jsp should contain " + expected + ".",
452: editorOper.contains(expected));
453: expected = "</h:form>";
454: assertTrue("index.jsp should contain " + expected + ".",
455: editorOper.contains(expected));
456: expected = "</f:view>";
457: assertTrue("index.jsp should contain " + expected + ".",
458: editorOper.contains(expected));
459:
460: editorOper.makeComponentVisible();
461: paletteOper.selectComponent("JSF Data Table");
462: paletteOper.pushKey(KeyEvent.VK_ENTER);
463: new NbDialogOperator("Insert JSF Data Table").ok();
464: expected = "<h:dataTable value=\"#{arrayOrCollectionOf}\" var=\"item\">";
465: assertTrue("index.jsp should contain " + expected + ".",
466: editorOper.contains(expected));
467: expected = "</h:dataTable>";
468: assertTrue("index.jsp should contain " + expected + ".",
469: editorOper.contains(expected));
470: }
471:
472: /** If installed visualweb cluster in IDE, switch from PageFlow to XML view of faces-config.xml.
473: * @return EditorOperator instance of faces-config.xml
474: */
475: public static EditorOperator getFacesConfig() {
476: TopComponentOperator tco = new TopComponentOperator(
477: "faces-config.xml");
478: if (JToggleButtonOperator.findJToggleButton((Container) tco
479: .getSource(), ComponentSearcher
480: .getTrueChooser("Toggle button")) != null) {
481: // "XML"
482: String xmlLabel = Bundle.getStringTrimmed(
483: "org.netbeans.modules.xml.multiview.Bundle",
484: "LBL_XML_TAB");
485: JToggleButtonOperator tbo = new JToggleButtonOperator(tco,
486: xmlLabel);
487: tbo.push();
488: }
489: return new EditorOperator("faces-config.xml");
490: }
491: }
|