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-2006 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:
042: package org.netbeans.test.junit4;
043:
044: import java.io.BufferedReader;
045: import java.io.File;
046: import java.io.FileNotFoundException;
047: import java.io.FileReader;
048: import java.io.IOException;
049: import java.util.ArrayList;
050: import java.util.Date;
051: import org.netbeans.jellytools.EditorOperator;
052: import org.netbeans.jellytools.JellyTestCase;
053: import org.netbeans.jellytools.NbDialogOperator;
054: import org.netbeans.jellytools.NewFileNameLocationStepOperator;
055: import org.netbeans.jellytools.NewFileWizardOperator;
056: import org.netbeans.jellytools.ProjectsTabOperator;
057: import org.netbeans.jellytools.actions.Action;
058: import org.netbeans.jellytools.actions.ActionNoBlock;
059: import org.netbeans.jellytools.actions.DeleteAction;
060: import org.netbeans.jellytools.actions.OpenAction;
061: import org.netbeans.jellytools.nodes.Node;
062: import org.netbeans.jellytools.nodes.ProjectRootNode;
063: import org.netbeans.jemmy.operators.JButtonOperator;
064: import org.netbeans.jemmy.operators.Operator;
065:
066: /**
067: * Class with helpers for easy creating jemmy/jelly tests
068: *
069: * @author Jiri Vagner
070: */
071: public abstract class ExtJellyTestCase extends JellyTestCase {
072:
073: private static int MY_WAIT_MOMENT = 500;
074:
075: public static String TEST_PROJECT_NAME = "JUnit4TestProject"; // NOI18N
076: public static String TEST_PACKAGE_NAME = "junit4testproject"; // NOI18N
077: public static String DELETE_OBJECT_CONFIRM = "Confirm Object Deletion"; // NOI18N
078: /* Skip file (JFrame,Frame, JDialog, ...) delete in the end of each test */
079: public Boolean DELETE_FILES = false;
080:
081: /** Constructor required by JUnit */
082: public ExtJellyTestCase(String testName) {
083: super (testName);
084: }
085:
086: /**
087: * Simple console println
088: */
089: public void p(String msg) {
090: System.out.println(msg);
091: }
092:
093: /**
094: * Simple console println
095: */
096: public void p(Boolean msg) {
097: p(String.valueOf(msg));
098: }
099:
100: /**
101: * Simple console println
102: */
103: public void p(int msg) {
104: p(String.valueOf(msg));
105: }
106:
107: /**
108: * Creates new file using NB New File Wizzard
109: * @return name of a new file
110: * @param project name of project to create file in
111: * @param packageName package for a new file
112: * @param category category from first step of new file wizzard
113: * @param fileType filetype from first step of new file wizzard
114: * @param name name prefix of a new file, timestamp will be added to avoid name clash
115: */
116: private String createFile(String project, String packageName,
117: String category, String fileType, String name) {
118: return createFile(project, packageName, category, fileType,
119: name, null);
120: }
121:
122: public String getTimeStamp() {
123: return String.valueOf(new Date().getTime());
124: }
125:
126: private String createFile(String project, String packageName,
127: String category, String fileType, String name,
128: String beanName) {
129: NewFileWizardOperator nfwo = NewFileWizardOperator.invoke();
130: nfwo.selectProject(project);
131: nfwo.selectCategory(category);
132: nfwo.selectFileType(fileType);
133: nfwo.next();
134:
135: String fileName = name + String.valueOf(new Date().getTime());
136:
137: if (beanName == null) {
138: NewFileNameLocationStepOperator nfnlso = new NewFileNameLocationStepOperator();
139: nfnlso.txtObjectName().clearText();
140: nfnlso.txtObjectName().typeText(fileName);
141: nfnlso.setPackage(packageName);
142: nfnlso.finish();
143: } else {
144: // NewBeanFormOperator nbfOp = new NewBeanFormOperator();
145: // nbfOp.txtClassName().clearText();
146: // nbfOp.txtClassName().typeText(fileName);
147: //
148: // nbfOp.cboPackage().clearText();
149: // nbfOp.typePackage(packageName);
150: //
151: // nbfOp.next();
152: //
153: // NewBeanFormSuperclassOperator superOp = new NewBeanFormSuperclassOperator();
154: // superOp.setSuperclass(beanName);
155: // superOp.finish();
156: }
157:
158: // following code avoids issue nr. 60418
159: ProjectsTabOperator pto = new ProjectsTabOperator();
160: ProjectRootNode prn = pto.getProjectRootNode(project);
161: prn.select();
162: Node formnode = new Node(prn, "Source Packages|" + packageName
163: + "|" + fileName); // NOI18N
164: formnode.select();
165:
166: OpenAction openAction = new OpenAction();
167: openAction.perform(formnode);
168: // end of issue code
169: return fileName;
170: }
171:
172: /**
173: * Removes file from actual project and actual test package
174: */
175: public void removeFile(String fileName) {
176: if (DELETE_FILES) {
177: ProjectsTabOperator project = new ProjectsTabOperator();
178: Node node = new Node(project.tree(), TEST_PROJECT_NAME
179: + "|Source Packages|" + TEST_PACKAGE_NAME + "|"
180: + fileName + ".java"); // NOI18N
181: DeleteAction act = new DeleteAction();
182: act.performPopup(node);
183:
184: //new NbDialogOperator(DELETE_OBJECT_CONFIRM).yes();
185: NbDialogOperator op = new NbDialogOperator("Safe Delete");
186: new JButtonOperator(op, "Refactor").clickMouse();
187: }
188: }
189:
190: /**
191: * Adds new bean into palette
192: *
193: * @param beanFileName
194: */
195: public void addBean(String beanFileName) {
196: // Node fileNode = openFile(beanFileName);
197: // waitAMoment();
198: //
199: // new ActionNoBlock("Tools|Add To Palette...", null).perform(); // NOI18N
200: // SelectPaletteCategoryOperator op = new SelectPaletteCategoryOperator();
201: // op.lstPaletteCategories().selectItem(SelectPaletteCategoryOperator.ITEM_BEANS);
202: // op.ok();
203: //
204: // CompileAction compAct = new CompileAction();
205: // compAct.perform(fileNode);
206: // waitAMoment();
207: }
208:
209: /**
210: * Opens file into nb editor
211: * @param fileName
212: * @return node
213: */
214: public Node openFile(String fileName) {
215: return getProjectFileNode(fileName, true, false);
216: }
217:
218: /**
219: * Gets file node from nb project tree
220: * @param fileName
221: * @return node
222: */
223: private Node getProjectFileNode(String filePath,
224: boolean openFileInEditor, boolean containsFilePathPackage) {
225: ProjectsTabOperator pto = new ProjectsTabOperator();
226: ProjectRootNode prn = pto.getProjectRootNode(TEST_PROJECT_NAME);
227: prn.select();
228:
229: String path = "Source Packages|";
230: if (!containsFilePathPackage) {
231: path += TEST_PACKAGE_NAME + "|"; // NOI18N
232: }
233: path += filePath;
234:
235: //p(path);
236: Node formnode = new Node(prn, path); // NOI18N
237: formnode.setComparator(new Operator.DefaultStringComparator(
238: true, false));
239: formnode.select();
240:
241: if (openFileInEditor) {
242: OpenAction openAction = new OpenAction();
243: openAction.perform(formnode);
244: }
245:
246: return formnode;
247: }
248:
249: public Node getProjectFileNode(String fileName) {
250: return getProjectFileNode(fileName, false, false);
251: }
252:
253: public Node getProjectFileNode(String fileName,
254: boolean containsFilePathPackage) {
255: return getProjectFileNode(fileName, false,
256: containsFilePathPackage);
257: }
258:
259: public Node getProjectFileNode(String fileName, String packageName) {
260: return getProjectFileNode(packageName + "|" + fileName, false,
261: true);
262: }
263:
264: public String createBeanFormFile(String beanClassName) {
265: return createFile(TEST_PROJECT_NAME, TEST_PACKAGE_NAME,
266: "Swing GUI Forms", "Bean Form", "MyBeanForm",
267: beanClassName); // NOI18N
268: }
269:
270: /**
271: * Creates new JDialog file in project
272: * @return new file name
273: */
274: public String createJDialogFile() {
275: return createFile(TEST_PROJECT_NAME, TEST_PACKAGE_NAME,
276: "Swing GUI Forms", "JDialog Form", "MyJDialog"); // NOI18N
277: }
278:
279: /**
280: * Creates new JFrame file in project
281: * @return new file name
282: */
283: public String createJFrameFile() {
284: return createFile(TEST_PROJECT_NAME, TEST_PACKAGE_NAME,
285: "Swing GUI Forms", "JFrame Form", "MyJFrame"); // NOI18N
286: }
287:
288: /**
289: * Creates new AWT Frame file in project
290: * @return new file name
291: */
292: public String createFrameFile() {
293: return createFile(TEST_PROJECT_NAME, TEST_PACKAGE_NAME,
294: "AWT GUI Forms", "Frame Form", "MyFrame"); // NOI18N
295: }
296:
297: /**
298: * Runs popoup command over node
299: * @param popup command, ex.: "Add|Swing|Label"
300: * @param node to run action on
301: */
302: public void runPopupOverNode(String actionName, Node node) {
303: Action act = new Action(null, actionName);
304: act.setComparator(new Operator.DefaultStringComparator(false,
305: false));
306: act.perform(node);
307: // p(actionName);
308: }
309:
310: /**
311: * Runs popoup command over node using NoBlockAction
312: * @param popup command, ex.: "Add|Swing|Label"
313: * @param node to run action on
314: */
315: public void runNoBlockPopupOverNode(String actionName, Node node) {
316: Action act = new ActionNoBlock(null, actionName);
317: act.setComparator(new Operator.DefaultStringComparator(false,
318: false));
319: act.perform(node);
320: // p(actionName);
321: }
322:
323: /**
324: * Runs popup commands over node
325: * @param array list of popup commands
326: * @param node to run actions on
327: */
328: public void runPopupOverNode(ArrayList<String> actionNames,
329: Node node, Operator.DefaultStringComparator comparator) {
330: for (String actionName : actionNames) {
331: Action act = new Action(null, actionName);
332: act.setComparator(comparator);
333: act.perform(node);
334: // p(actionName);
335: }
336: }
337:
338: /**
339: * Runs popup commands over node
340: * @param array list of popup commands
341: * @param node to run actions on
342: */
343: public void runPopupOverNode(ArrayList<String> actionNames,
344: Node node) {
345: runPopupOverNode(actionNames, node,
346: new Operator.DefaultStringComparator(false, false));
347: }
348:
349: /**
350: * Find a substring in a string
351: * Test fail() method is called, when code string doesnt contain stringToFind.
352: * @param stringToFind string to find
353: * @param string to search
354: */
355: private void findStringInCode(String stringToFind, String code) {
356: if (!code.contains(stringToFind)) {
357: fail("Missing string \"" + stringToFind + "\" in code."); // NOI18N
358: }
359: }
360:
361: /**
362: * Find a strings in a code
363: * @param lines array list of strings to find
364: * @param designer operator "with text"
365: */
366: public void findInCode(ArrayList<String> lines,
367: EditorOperator editor) {
368: String code = editor.getText();
369:
370: for (String line : lines) {
371: findStringInCode(line, code);
372: }
373: }
374:
375: /**
376: * Find a string in a code
377: * @param lines array list of strings to find
378: * @param designer operator "with text"
379: */
380: public void findInCode(String stringToFind, EditorOperator editor) {
381: findStringInCode(stringToFind, editor.getText());
382: }
383:
384: /**
385: * Miss a string in a code
386: * Test fail() method is called, when code contains stringToFind string
387: * @param stringToFind
388: * @param designer operator "with text"
389: */
390: public void missInCode(String stringToFind, EditorOperator editor) {
391: if (editor.getText().contains(stringToFind)) {
392: fail("String \"" + stringToFind + "\" found in code."); // NOI18N
393: }
394: }
395:
396: /**
397: * Calls Jelly waitNoEvent()
398: * @param quiet time (miliseconds)
399: */
400: public static void waitNoEvent(long waitTimeout) {
401: new org.netbeans.jemmy.EventTool().waitNoEvent(waitTimeout);
402: }
403:
404: /**
405: * Calls Jelly waitNoEvent() with MY_WAIT_MOMENT
406: */
407: public static void waitAMoment() {
408: waitNoEvent(MY_WAIT_MOMENT);
409: }
410:
411: /** Find msg string in file
412: *
413: * @result boolean
414: */
415: public static boolean findInFile(String msg, String filePath) {
416: String content = getContents(new File(filePath));
417: return content.indexOf(msg) != -1;
418: }
419:
420: /**
421: * Fetch the entire contents of a text file, and return it in a String.
422: * This style of implementation does not throw Exceptions to the caller.
423: *
424: * @param aFile is a file which already exists and can be read.
425: */
426: public static String getContents(File aFile) {
427: //...checks on aFile are elided
428: StringBuffer contents = new StringBuffer();
429:
430: //declared here only to make visible to finally clause
431: BufferedReader input = null;
432: try {
433: //use buffering, reading one line at a time
434: //FileReader always assumes default encoding is OK!
435: input = new BufferedReader(new FileReader(aFile));
436: String line = null; //not declared within while loop
437: /*
438: * readLine is a bit quirky :
439: * it returns the content of a line MINUS the newline.
440: * it returns null only for the END of the stream.
441: * it returns an empty String if two newlines appear in a row.
442: */
443: while ((line = input.readLine()) != null) {
444: contents.append(line);
445: contents.append(System.getProperty("line.separator"));
446: }
447: } catch (FileNotFoundException ex) {
448: ex.printStackTrace();
449: } catch (IOException ex) {
450: ex.printStackTrace();
451: } finally {
452: try {
453: if (input != null) {
454: //flush and close both "input" and its underlying FileReader
455: input.close();
456: }
457: } catch (IOException ex) {
458: ex.printStackTrace();
459: }
460: }
461: return contents.toString();
462: }
463:
464: /** Gets full path to file from "data" package from SampleProject
465: * @param short file name with extension (e.g TestFrame.java);
466: * @result full path to file (e.g /home/jirka/TestFrame.java)
467: */
468: public String getFilePathFromDataPackage(String fileName) {
469: return getDataDir().getAbsolutePath() + File.separatorChar
470: + TEST_PROJECT_NAME + File.separatorChar + "src"
471: + File.separatorChar + TEST_PACKAGE_NAME
472: + File.separatorChar + fileName; // NOI18N
473: }
474: }
|