/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License. When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* The Original Software is NetBeans. The Initial Developer of the Original
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
* Microsystems, Inc. All Rights Reserved.
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*/
/*
* EditorTestCase.java
*
* Created on 24. srpen 2004, 12:32
*/
package lib;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.util.StringTokenizer;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import org.netbeans.jellytools.EditorOperator;
import org.netbeans.jellytools.JellyTestCase;
import org.netbeans.jellytools.NbDialogOperator;
import org.netbeans.jellytools.ProjectsTabOperator;
import org.netbeans.jellytools.nodes.Node;
import org.netbeans.jellytools.nodes.ProjectRootNode;
import org.netbeans.jemmy.JemmyException;
import org.netbeans.jemmy.JemmyProperties;
import org.netbeans.jemmy.TimeoutExpiredException;
import org.netbeans.jemmy.Waitable;
import org.netbeans.jemmy.Waiter;
import org.netbeans.jemmy.operators.ComponentOperator;
import org.netbeans.jemmy.operators.JEditorPaneOperator;
import org.netbeans.jemmy.operators.JTextFieldOperator;
//retouche:
//import org.netbeans.junit.ide.ProjectSupport;
/**
*
* @author Petr Felenda, Martin Roskanin
*/
public class EditorTestCase extends JellyTestCase {
private static final int OPENED_PROJECT_ACCESS_TIMEOUT = 1000;
/** Default name of project is used if not specified in openProject method. */
private String defaultProjectName = "SampleProject";
// private String defaultSamplePackage = "dummy";
// private String defaultSampleName = "sample1";
private static final char treeSeparator = '|';
private final String defaultPackageNameTreePath = "Source packages"+treeSeparator+"dummy";
private final String defaultFileName = "sample1";
private String projectName = null;
private String treeSubPackagePathToFile = null;
private String fileName = null;
private final String dialogSaveTitle = "Save"; // I18N
public static final int WAIT_MAX_MILIS_FOR_CLIPBOARD = 4000;
/**
* Creates a new instance of EditorTestCase.
*
* <p>
* Initializes default sample file name (package and name)
* so that {@link #openDefaultSampleFile()} can be used.
* <br>
* The rule for naming is the same like for golden files
* i.e. package corresponds to the class name and the file
* name corresponds to test method name.
*
* @param testMethodName name of the test method
* that should be executed.
*/
public EditorTestCase(String testMethodName) {
super(testMethodName);
// defaultSamplePackage = getClass().getName();
// defaultSampleName = getName();
}
/**
* Split class full name into package name and class name.
*
* @param full name of the class
* @return array containing package name and the class name.
*/
/* public static String[] splitClassName(String classFullName) {
int lastDotIndex = classFullName.lastIndexOf('.');
return new String[] {
(lastDotIndex >= 0) ? classFullName.substring(0, lastDotIndex) : "", // pkg name
classFullName.substring(lastDotIndex + 1) // class name
};
}
*/
/** Open project. Before opening the project is checked opened projects.
* @param projectName is name of the project stored in .../editor/test/qa-functional/data/ directory.
*/
public void openProject(String projectName) {
this.projectName = projectName;
File projectPath = new File(this.getDataDir() + "/projects", projectName);
log("data dir = "+this.getDataDir().toString());
/* 1. check if project is open */
ProjectsTabOperator pto = new ProjectsTabOperator();
pto.invoke();
boolean isOpen = true;
try {
JemmyProperties.setCurrentTimeout("JTreeOperator.WaitNextNodeTimeout", OPENED_PROJECT_ACCESS_TIMEOUT);
ProjectRootNode prn = pto.getProjectRootNode(projectName);
} catch (TimeoutExpiredException ex) {
// This excpeiton is ok, project is not open;
//ex.printStackTrace();
isOpen = false;
}
if ( isOpen ) {
log("Project is open!");
return;
}
/* 2. open project */
//retouche:
// Object prj= ProjectSupport.openProject(projectPath);
}
/**
* Get the default project name to be used
* in {@link openDefaultProject()}.
* <br>
* The default value is "editor_test".
*
* @return default project name
*/
protected String getDefaultProjectName() {
return defaultProjectName;
}
/**
* Set the default project name to be used
* in {@link openDefaultProject()}.
*
* @param defaultProjectName new default project name.
*/
/*
protected void setDefaultProjectName(String defaultProjectName) {
this.defaultProjectName = defaultProjectName;
}
*/
/**
* Open default project determined
* by {@link #getDefaultProjectName()}.
*/
protected void openDefaultProject() {
openProject(getDefaultProjectName());
}
/**
* Close the default project.
*/
protected void closeDefaultProject() {
closeProject(getDefaultProjectName());
}
protected void closeProject(String projectName) {
//retouche:
// ProjectSupport.closeProject(projectName);
}
/** Open file in open project
* @param treeSubPath e.g. "Source Packages|test","sample1" */
public void openFile(String treeSubPackagePathToFile, String fileName) {
// debug info, to be removed
this.treeSubPackagePathToFile = treeSubPackagePathToFile;
ProjectsTabOperator pto = new ProjectsTabOperator();
pto.invoke();
ProjectRootNode prn = pto.getProjectRootNode(projectName);
prn.select();
// fix of issue #51191
// each of nodes is checked by calling method waitForChildNode
// before they are actually opened
StringTokenizer st = new StringTokenizer(treeSubPackagePathToFile,
treeSeparator+"");
String token = "";
String oldtoken = "";
// if there are more then one tokens process each of them
if (st.countTokens()>1) {
token = st.nextToken();
String fullpath = token;
while (st.hasMoreTokens()) {
token = st.nextToken();
waitForChildNode(fullpath, token);
fullpath += treeSeparator+token;
}
}
// last node
waitForChildNode(treeSubPackagePathToFile, fileName);
// end of fix of issue #51191
Node node = new Node(prn,treeSubPackagePathToFile+treeSeparator+fileName);
node.performPopupAction("Edit");
}
/**
* Waits for a child node to be shown in the IDE. Needed for test
* stabilization on slow machines.
* @param parentPath full path for parent, | used as a delimiter
* @param childName name of the child node
*/
public void waitForChildNode(String parentPath, String childName) {
ProjectsTabOperator pto = new ProjectsTabOperator();
ProjectRootNode prn = pto.getProjectRootNode(projectName);
prn.select();
Node parent = new Node(prn, parentPath);
final String finalFileName = childName;
try {
// wait for max. 30 seconds for the file node to appear
JemmyProperties.setCurrentTimeout("Waiter.WaitingTime", 30000);
new Waiter(new Waitable() {
public Object actionProduced(Object parent) {
return ((Node)parent).isChildPresent(finalFileName) ?
Boolean.TRUE: null;
}
public String getDescription() {
return("Waiting for the tree to load.");
}
}).waitAction(parent);
} catch (InterruptedException e) {
throw new JemmyException("Interrupted.", e);
}
}
/** Open the default file in open project */
public void openFile() {
openFile(defaultPackageNameTreePath,defaultFileName);
}
/** Close file in open project.
*/
public void closeFile() {
try {
new EditorOperator(fileName).close();
} catch ( TimeoutExpiredException ex) {
log(ex.getMessage());
log("Can't close the file");
}
}
/** Close file in open project.
*/
public void closeFileWithSave() {
try {
new EditorOperator(fileName).close(true);
} catch ( TimeoutExpiredException ex) {
log(ex.getMessage());
log("Can't close the file");
}
}
/** Close file in open project.
*/
public void closeFileWithDiscard() {
try {
new EditorOperator(fileName).closeDiscard();
} catch ( TimeoutExpiredException ex) {
log(ex.getMessage());
log("Can't close the file");
}
}
/** Close dialog with added title
* @param title dialog title */
public void closeDialog(String title) {
NbDialogOperator dialog = new NbDialogOperator(title);
dialog.closeByButton();
}
/**
* Write the text of the passed document to the ref file
* and compare the created .ref file with the golden file.
* <br>
* If the two files differ the test fails and generates the diff file.
*
* @param testDoc document to be written to the .ref file and compared.
*/
protected void compareReferenceFiles(Document testDoc) {
try {
ref(testDoc.getText(0, testDoc.getLength()));
compareReferenceFiles();
} catch (BadLocationException e) {
e.printStackTrace(getLog());
fail();
}
}
/**
* Open a source file located in the "Source packages" in the editor.
*
* @param dir directory path with "|" separator.
* @param srcName source name without suffix.
*/
protected void openSourceFile(String dir, String srcName) {
openFile(org.netbeans.jellytools.Bundle.getString("org.netbeans.modules.java.j2seproject.Bundle", "NAME_src.dir")+treeSeparator+dir, srcName);
}
// protected final String getDefaultSamplePackage() {
// return defaultSamplePackage;
// }
//
// protected final String getDefaultSampleName() {
// return defaultSampleName;
// }
// protected void openDefaultSampleFile() {
// openSourceFile(defaultSamplePackage, defaultSampleName);
// }
// protected EditorOperator getDefaultSampleEditorOperator() {
// return new EditorOperator(defaultSampleName);
// }
/** Method will wait max. <code> maxMiliSeconds </code> miliseconds for the <code> requiredValue </code>
* gathered by <code> resolver </code>.
*
* @param maxMiliSeconds maximum time to wait for requiredValue
* @param resolver resolver, which is gathering an actual value
* @param requiredValue if resolver value equals requiredValue the wait cycle is finished
*
* @return false if the given maxMiliSeconds time elapsed and the requiredValue wasn't obtained
*/
protected boolean waitMaxMilisForValue(int maxMiliSeconds, ValueResolver resolver, Object requiredValue){
int time = (int) maxMiliSeconds / 100;
while (time > 0) {
Object resolvedValue = resolver.getValue();
if (requiredValue == null && resolvedValue == null){
return true;
}
if (requiredValue != null && requiredValue.equals(resolvedValue)){
return true;
}
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException ex) {
time=0;
}
time--;
}
return false;
}
/** Interface for value resolver needed for i.e. waitMaxMilisForValue method.
* For more details, please look at {@link #waitMaxMilisForValue()}.
*/
public static interface ValueResolver{
/** Returns checked value */
Object getValue();
}
protected ValueResolver getClipboardResolver(final JEditorPaneOperator txtOper, final int key, final int mod, final String oldVal){
ValueResolver clipboardValueResolver = new ValueResolver(){
public Object getValue(){
txtOper.pushKey(key, mod);
Transferable newClipValue = txtOper.getToolkit().getSystemClipboard().getContents(txtOper);
String newVal = getClipBoardContent(newClipValue);
log("newClipValue:"+newVal);
return (newVal.equals(oldVal)) ? Boolean.TRUE : Boolean.FALSE;
}
};
return clipboardValueResolver;
}
protected ValueResolver getTextFieldResolver(final JTextFieldOperator oper,final String newValue) {
ValueResolver textFieldResolver = new ValueResolver(){
public Object getValue(){
String actVal = oper.getText();
log("actual value:"+actVal);
return (newValue.equals(actVal)) ? Boolean.TRUE : Boolean.FALSE;
}
};
return textFieldResolver;
}
private String getClipBoardContent(Transferable clip) {
DataFlavor[] df = clip.getTransferDataFlavors();
for (int i = 0; i < df.length; i++) {
DataFlavor dataFlavor = df[i];
log("Mime: "+dataFlavor.getMimeType());
log("Class: "+dataFlavor.getRepresentationClass().getName());
log("Class2: "+dataFlavor.getDefaultRepresentationClass().getName());
try {
log(clip.getTransferData(dataFlavor).getClass().getName());
} catch(IOException ioe) {
} catch (UnsupportedFlavorException ufe) {
}
}
String val = null;
try {
val = (String) clip.getTransferData(new DataFlavor("text/plain; class=java.lang.String; charset=Unicode"));
} catch (UnsupportedFlavorException ex) {
fail(ex);
} catch (IOException ex) {
fail(ex);
} catch (ClassNotFoundException ex) {
fail(ex);
}
return val;
}
protected void cutCopyViaStrokes(JEditorPaneOperator txtOper, int key, int mod){
Transferable oldClipValue = txtOper.getToolkit().getSystemClipboard().getContents(txtOper);
String oldVal = getClipBoardContent(oldClipValue);
log("");
log("oldClipValue:"+oldVal);
txtOper.requestFocus();
txtOper.pushKey(key, mod);
// give max WAIT_MAX_MILIS_FOR_CLIPBOARD milis for clipboard to change
boolean success = waitMaxMilisForValue(WAIT_MAX_MILIS_FOR_CLIPBOARD, getClipboardResolver(txtOper, key, mod, oldVal), Boolean.FALSE);
if (success == false){
// give it one more chance. maybe selection was not ready at the time of
// copying
log("!!!! ONCE AGAIN");
txtOper.pushKey(key, mod);
// give max WAIT_MAX_MILIS_FOR_CLIPBOARD milis for clipboard to change
waitMaxMilisForValue(WAIT_MAX_MILIS_FOR_CLIPBOARD, getClipboardResolver(txtOper, key, mod, oldVal), Boolean.FALSE);
}
}
protected void pasteViaStrokes(ComponentOperator compOper, int key, int mod, ValueResolver resolver){
compOper.pushKey(key, mod);
// give max WAIT_MAX_MILIS_FOR_CLIPBOARD milis for clipboard to change
if (resolver !=null){
boolean success = waitMaxMilisForValue(WAIT_MAX_MILIS_FOR_CLIPBOARD, resolver, Boolean.TRUE);
if (success == false){
// give it one more chance.
compOper.pushKey(key, mod);
// give max WAIT_MAX_MILIS_FOR_CLIPBOARD milis for clipboard to change
waitMaxMilisForValue(WAIT_MAX_MILIS_FOR_CLIPBOARD, resolver, Boolean.TRUE);
}
}
}
}
|