alexruiz / fest-swing-1.x Goto Github PK
View Code? Open in Web Editor NEWFEST Functional Swing Testing
Home Page: http://fest.easytesting.org
FEST Functional Swing Testing
Home Page: http://fest.easytesting.org
Our gui tests fail every now and then due to the below error. They are executed in the early morning ours on a jenkins. Our code seems to be ok since it on some days the tests pass just ok.
We use version 1.2.1 of fest-swing and 1.1.6 of fest-util. We first thought it is a matter of the versions used since we first have been using 1.2 fest-swing. However, still after the upgrade the tests fail.
What could be the reason for the failures?
Focus change to com.glady.tanon.air.client.common.component.DoubleTextField[name='percentDTF', text='0', enabled=true, visible=true, showing=true] failed
Stacktrace
org.fest.swing.exception.ActionFailedException: Focus change to com.glady.tanon.air.client.common.component.DoubleTextField[name='percentDTF', text='0', enabled=true, visible=true, showing=true] failed
at org.fest.swing.exception.ActionFailedException.actionFailure(ActionFailedException.java:33)
at org.fest.swing.core.BasicRobot.focus(BasicRobot.java:271)
at org.fest.swing.core.BasicRobot.focusAndWaitForFocusGain(BasicRobot.java:248)
at org.fest.swing.driver.ComponentDriver.focusAndWaitForFocusGain(ComponentDriver.java:363)
at org.fest.swing.driver.JTextComponentDriver.setText(JTextComponentDriver.java:143)
at org.fest.swing.fixture.JTextComponentFixture.setText(JTextComponentFixture.java:225)
at com.glady.tanon.air.client.swing.guiapi.common.GuiTester.setText(GuiTester.java:193)
at com.glady.tanon.air.client.swing.guiapi.dialogues.deal.pricingrequest.PricingRequestairPzSubDialogue.fillDataForPricezonePercent(PricingRequestairPzSubDialogue.java:79)
at com.glady.tanon.air.client.swing.guiapi.dialogues.deal.pricingrequest.PricingRequestairDialogue.setPricezones(PricingRequestairDialogue.java:199)
at com.glady.tanon.air.client.swing.guiapi.dialogues.deal.pricingrequest.PricingRequestairDialogue.setCompleteData(PricingRequestairDialogue.java:242)
at com.glady.tanon.air.client.swing.guitests.acceptance.TrancheAcceptanceTestImpl.createSignedContract(TrancheAcceptanceTestImpl.java:101)
at com.glady.tanon.air.client.swing.guitests.acceptance.TrancheAcceptanceTestImpl.testCosting(TrancheAcceptanceTestImpl.java:37)
at com.glady.tanon.air.client.swing.guitests.acceptance.TestSuiteAcceptanceTestGuiNoDataset.testTranches(TestSuiteAcceptanceTestGuiNoDataset.java:35)
at com.glady.tanon.air.client.swing.guitests.acceptance.TestSuiteAcceptanceTestGui.testTranches(TestSuiteAcceptanceTestGui.java:32)
Constructor uses 'cel()' instead of 'cell', which will always set cell to null because cell() returns cell which isn't initialized :)
Hi,
It would be nice if we could configure/disable the call stack eating of assertions in the GuiActionRunner. We do not understand why appending (as you do for runtimeExceptions) would not be better than replacing.
Regards,
Rob.
Comparing using UTF-8 to GBK, only one of them can work, I'm not sure if or not it is a bug of Fest Swing or Swing itself.
command line to work:
java -Dfile.encoding=UTF-8 -cp ... TestFrame
command line to repeate error (My PC is Windows XP Chinese version, GBK is defaulted code page):
java -Dfile.encoding=GBK -cp ... TestFrame
org.fest.swing.exception.ActionFailedException: Unable to make visible the location of the index '0' by scrolling the point (1,-1) on javax.swing.JTextField[name='Table.editor', text='A2', enabled=true, visible=true, showing=true]
at org.fest.swing.exception.ActionFailedException.actionFailure(ActionFailedException.java:33)
I also tried to test if or not cell not found results in such error, but when the cell value not found, the error message is Unable to find cell matching value 'B2DD':
grid.enterValue(grid.cell("B2DD"), "B2*");
file versions:
fest-asset-1.2.jar
fest-swing-1.2.jar
fest-reflect-1.2.jar
fest-util-1.1.2.jar
JRE (x86 version) :
java version "1.7.0"
Java(TM) SE Runtime Environment (build 1.7.0-b147)
Java HotSpot(TM) Client VM (build 21.0-b17, mixed mode, sharing)
Machine:
Windows XP SP3 Chinese language (GBK is default code page).
Sample Code:
final JFrame frame = new JFrame();
frame.setTitle("FEST Swing");
{
String[][] matrix = new String[][] { { "A1", "A2", "A3" },
{ "B1", "B2", "B3" } };
String[] headers = new String[] { "A", "B", "C" };
JTable g = new JTable(matrix, headers);
g.setName("Grid");
frame.getContentPane().add(g);
}
frame.setBounds(100, 100, 500, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FrameFixture target = new FrameFixture(frame);
target.show();
JTableFixture grid = target.table("Grid");
grid.enterValue(grid.cell("A2"), "A2*"); // error reported here.
grid.enterValue(grid.cell("B2"), "B2*");
Unfortunately, I cannot give you any source code examples and this bug doesn't occur permanently.
We have several JToggleButtons in our dialog. Initially, they are all selected. In our FEST test case we execute a double click on their JToggleButtonFixtures. The first click seems to be executed, but sometimes the second click won't be applied by FEST.
I checked this via several System.outs added to item listener list of these buttons.
Two single click invocations do the job as well. But if you provide double click then this should work, too.
This test cannot be compiled still, very minor fix
The easytesting.org site has been down for quite some time. Due to this the online javadoc is also inaccessible.
The special logic for OS X menu item clicking causes a problem when applied to popup menu items that invoke a dialog. In my test case, what happens is that focus is returned immediately to the Window frame where the popup menu was invoked instead of remaining on the newly popped up dialog.
Modifying JMenuItemDriver to first check whether the menu item is an actual menu bar item first prevents this from happening.
This focus behavior is something new that I hadn't experienced under Apple Java 6 with fest-swing 1.2.1
@RunsInEDT
private void doClick(@Nonnull JMenuItem menuItem) {
// ONLY USE OS X LOGIC ON MENU BAR MENU ITEMS
if (menuItem instanceof JMenu && locationOf(menuItem).inMenuBar()) {
if (isMacOSMenuBar()) {
validateAndDoClick(menuItem);
return;
}
}
super.click(menuItem);
robot.waitForIdle();
}
I am trying to run FEST tests under Mac OS X 10.7.4 x86_64 using Oracle Corporation 1.7.0_06
The Oracle JDK for OS X is available at [http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1637583.html]
When trying to click on a menu item FEST returns the following Exception:
Running on:
Exception in thread "main" org.fest.swing.exception.ActionFailedException: Clicking on menu item <javax.swing.JMenu[name=null, text='File', selected=false, enabled=true, visible=true, showing=true]> never showed a pop-up menu
at org.fest.swing.exception.ActionFailedException.actionFailure(ActionFailedException.java:33)
at org.fest.swing.driver.JMenuItemDriver.ensurePopupIsShowing(JMenuItemDriver.java:137)
at org.fest.swing.driver.JMenuItemDriver.click(JMenuItemDriver.java:73)
at org.fest.swing.driver.JMenuItemDriver.activateParentIfIsAMenu(JMenuItemDriver.java:97)
at org.fest.swing.driver.JMenuItemDriver.show(JMenuItemDriver.java:79)
at org.fest.swing.driver.JMenuItemDriver.click(JMenuItemDriver.java:71)
at org.fest.swing.fixture.JMenuItemFixture.click(JMenuItemFixture.java:84)
at com.test.NewSwingAppTest.doFESTtest(NewSwingAppTest.java:42)
at com.test.NewSwingAppTest.main(NewSwingAppTest.java:16)
See the code below:
package com.test;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JSeparator;
import javax.swing.SwingUtilities;
public class NewSwingApp extends javax.swing.JFrame {
/**
*
*/
private static final long serialVersionUID = -6489118287010615132L;
protected static final String OS_NAME = System.getProperty("os.name");
protected static final String OS_VERSION = System.getProperty("os.version");
protected static final String OS_ARCH = System.getProperty("os.arch");
protected static final String JAVA_VER = System.getProperty("java.version");
protected static final String JAVA_VENDOR = System.getProperty("java.vendor");
private JMenuItem helpMenuItem;
private JMenu jMenu5;
private JMenuItem deleteMenuItem;
private JSeparator jSeparator1;
private JMenuItem pasteMenuItem;
private JMenuItem copyMenuItem;
private JMenuItem cutMenuItem;
private JMenu jMenu4;
private JMenuItem exitMenuItem;
private JSeparator jSeparator2;
private JMenuItem closeFileMenuItem;
private JMenuItem saveAsMenuItem;
private JMenuItem saveMenuItem;
private JMenuItem openFileMenuItem;
private JMenuItem newFileMenuItem;
private JMenu jMenu3;
private JMenuBar jMenuBar1;
/**
* Auto-generated main method to display this JFrame
*/
public static void main(String[] args) {
System.setProperty("apple.laf.useScreenMenuBar", "true");
SwingUtilities.invokeLater(new Runnable() {
public void run() {
final NewSwingApp inst = new NewSwingApp();
inst.setLocationRelativeTo(null);
inst.setVisible(true);
}
});
}
public NewSwingApp() {
super();
initGUI();
System.out.println("\nRunning on:");
System.out.format("\tOS: %s %s %s\n", OS_NAME, OS_VERSION, OS_ARCH);
System.out.format("\tJava: %s %s\n", JAVA_VENDOR, JAVA_VER);
}
private void initGUI() {
try {
{
this.setTitle("NewSwingApp");
}
setSize(400, 300);
setPreferredSize(getSize());
setMaximumSize(getPreferredSize());
setMinimumSize(getPreferredSize());
{
this.jMenuBar1 = new JMenuBar();
setJMenuBar(this.jMenuBar1);
{
this.jMenu3 = new JMenu();
this.jMenuBar1.add(this.jMenu3);
this.jMenu3.setText("File");
{
this.newFileMenuItem = new JMenuItem();
this.jMenu3.add(this.newFileMenuItem);
this.newFileMenuItem.setText("New");
}
{
this.openFileMenuItem = new JMenuItem();
this.jMenu3.add(this.openFileMenuItem);
this.openFileMenuItem.setText("Open");
}
{
this.saveMenuItem = new JMenuItem();
this.jMenu3.add(this.saveMenuItem);
this.saveMenuItem.setText("Save");
}
{
this.saveAsMenuItem = new JMenuItem();
this.jMenu3.add(this.saveAsMenuItem);
this.saveAsMenuItem.setText("Save As ...");
}
{
this.closeFileMenuItem = new JMenuItem();
this.jMenu3.add(this.closeFileMenuItem);
this.closeFileMenuItem.setText("Close");
}
{
this.jSeparator2 = new JSeparator();
this.jMenu3.add(this.jSeparator2);
}
{
this.exitMenuItem = new JMenuItem();
this.jMenu3.add(this.exitMenuItem);
this.exitMenuItem.setText("Exit");
this.exitMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
System.exit(NORMAL);
}
});
}
}
{
this.jMenu4 = new JMenu();
this.jMenuBar1.add(this.jMenu4);
this.jMenu4.setText("Edit");
{
this.cutMenuItem = new JMenuItem();
this.jMenu4.add(this.cutMenuItem);
this.cutMenuItem.setText("Cut");
}
{
this.copyMenuItem = new JMenuItem();
this.jMenu4.add(this.copyMenuItem);
this.copyMenuItem.setText("Copy");
}
{
this.pasteMenuItem = new JMenuItem();
this.jMenu4.add(this.pasteMenuItem);
this.pasteMenuItem.setText("Paste");
}
{
this.jSeparator1 = new JSeparator();
this.jMenu4.add(this.jSeparator1);
}
{
this.deleteMenuItem = new JMenuItem();
this.jMenu4.add(this.deleteMenuItem);
this.deleteMenuItem.setText("Delete");
}
}
{
this.jMenu5 = new JMenu();
this.jMenuBar1.add(this.jMenu5);
this.jMenu5.setText("Help");
{
this.helpMenuItem = new JMenuItem();
this.jMenu5.add(this.helpMenuItem);
this.helpMenuItem.setText("Help");
}
}
}
} catch (final Exception e) {
e.printStackTrace();
}
}
}
package com.test;
import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
import org.fest.swing.edt.GuiActionRunner;
import org.fest.swing.edt.GuiQuery;
import org.fest.swing.fixture.FrameFixture;
public class NewSwingAppTest {
private NewSwingApp swingApp;
private FrameFixture window;
public static void main(String[] args) {
System.setProperty("apple.laf.useScreenMenuBar", "true");
doFESTtest();
}
public static void launchApp() {
final NewSwingApp inst = new NewSwingApp();
inst.setVisible(true);
}
public static void doFESTtest() {
FailOnThreadViolationRepaintManager.install();
final NewSwingAppTest testApp = new NewSwingAppTest();
testApp.swingApp = GuiActionRunner.execute(new GuiQuery<NewSwingApp>() {
protected NewSwingApp executeInEDT() {
final NewSwingApp inst = new NewSwingApp();
return inst;
}
});
testApp.window = new FrameFixture(testApp.swingApp);
testApp.window.robot.showWindow(testApp.window.target, null, false);
testApp.window.menuItemWithPath("File", "Exit").click();
}
}
Hi,
when I run test testcase under windows 10, it cann't click on the main menus,but on the title bar.
It works well on windows 7.
Under windows 10, the mouse alway click on the title bar,the showed a pop-up menu is like[MaximizeใMinimize ...]
How to make it click on the right menu bar on windows 10?
Thanks,
Johhny.
I hope you don't mind me posting issues I come across. I know you are currently working on this repository, but we are in urgent need of a version of FEST that will work with Java 1.7. The current code snapshot seems to address the problem I reported (Issue #2 ).
Hopefully there are only minor issues still remaining to address, like the following.
There are 2 '%s' format specifiers but only one argument provided.
Please let me know if you prefer I not continue posting issues I come across.
I've cloned from https://github.com/alexruiz/fest-swing-1.x.git into Netbeans (and a standalone directory to further confirm issue) and find errors against some files: [see below]
Also below is code to convert a key mapping file non-ASCII char to a numeric representation in hopes this will be useful in saving you time to create the update. It processes the whole Java file and saves it into a new file (saved).
org.fest.swing.keystroke.
KeyStrokeMappingProvider_de.java
KeyStrokeMappingProvider_fr.java
KeyStrokeMappingProvider_mac_fr-FR.java
The issue appears to be with git doing something to the special characters for key stroke mappings that use none ASCII chars. Below is an example where the encoding is damaged (********** marked) when I git clone the repository. I've also cloned to a standalone (command line used) directory on windows 7 wijh the same problem.
Doing a compare to downloaded zip files of Fest-Swing1.2 and looking at the sources.jar you can see what the special characters are. If I copy/paste the affected lines from the sources.jar to the NetBeans Ide the special characters show correctly and okay.
I've googled git for UTF and encoding issues and only found issues pertaining to file names with UTF-8.
Do you have any idea as to the cause and a possible fix?
(Ideally, for key stroke mappings character shouldn't be used, but utf code values should be for none ASCII chars [as is pointed out by discussion on UTF-8/internationlization advocates]).
Thx anyone
public Collection keyStrokeMappings() {
List mappings = new ArrayList(120);
mappings.addAll(defaultMappings());
mappings.add(mapping('0', VK_0, NO_MASK));
mappings.add(mapping('=', VK_0, SHIFT_MASK));
mappings.add(mapping('}', VK_0, ALT_GRAPH_MASK));
mappings.add(mapping('1', VK_1, NO_MASK));
mappings.add(mapping('!', VK_1, SHIFT_MASK));
mappings.add(mapping('2', VK_2, NO_MASK));
mappings.add(mapping('"', VK_2, SHIFT_MASK));
mappings.add(mapping('รฏยฟยฝ', VK_2, ALT_GRAPH_MASK)); ************
mappings.add(mapping('3', VK_3, NO_MASK));
mappings.add(mapping('รฏยฟยฝ', VK_3, SHIFT_MASK)); *************
mappings.add(mapping('รฏยฟยฝ', VK_0, ALT_GRAPH_MASK)); *************
mappings.add(mapping('4', VK_4, NO_MASK));
mappings.add(mapping('$', VK_4, SHIFT_MASK));
mappings.add(mapping('5', VK_5, NO_MASK));
mappings.add(mapping('%', VK_5, SHIFT_MASK));
public Collection keyStrokeMappings() {
List mappings = new ArrayList(120);
mappings.addAll(defaultMappings());
mappings.add(mapping('0', VK_0, NO_MASK));
mappings.add(mapping('=', VK_0, SHIFT_MASK));
mappings.add(mapping('}', VK_0, ALT_GRAPH_MASK));
mappings.add(mapping('1', VK_1, NO_MASK));
mappings.add(mapping('!', VK_1, SHIFT_MASK));
mappings.add(mapping('2', VK_2, NO_MASK));
mappings.add(mapping('"', VK_2, SHIFT_MASK));
mappings.add(mapping('ยฒ', VK_2, ALT_GRAPH_MASK)); *** correct
mappings.add(mapping('3', VK_3, NO_MASK));
mappings.add(mapping('ยง', VK_3, SHIFT_MASK)); *** correct
mappings.add(mapping('ยณ', VK_0, ALT_GRAPH_MASK)); *** correct
mappings.add(mapping('4', VK_4, NO_MASK));
mappings.add(mapping('$', VK_4, SHIFT_MASK));
mappings.add(mapping('5', VK_5, NO_MASK));
mappings.add(mapping('%', VK_5, SHIFT_MASK));
Code below will process a key mapping file and replace non-ascii chars with the code:
(char)178
package Iso8859JavaProcessor.main;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.ArrayList;
import javax.swing.JFileChooser;
/**
Class to convert ISO-8859-1 characters to numeric values for a format of
FEST-Swing KeyMappingProvider class java code. The whole file is input and
then output to another file with the conversion of only the special chars
changed.
For example:
mappings.add(mapping('ยฒ', VK_2, ALT_GRAPH_MASK));
converted to
mappings.add(mapping((char)178, VK_2, ALT_GRAPH_MASK));
the super-script 2 is an ALT+178
Via FileChooser provide an "OPEN" input file and then provide a "SAVE" output
file (different path).
/
public class ProcessingKeyMapperFESTSwing {
/* encoding for processing file on read and any non-ASCII special chars */
private static String encodingCode = "ISO-8859-1";
/**
/**
Main for application run.
@param args
arguments not used
*/
public static void main(String[] args) {
// perform the input file chooser
JFileChooser inputFileChooser = new JFileChooser();
int returnVal = inputFileChooser.showOpenDialog(null);
// if the item is approved then may set the path for processing
if (returnVal == JFileChooser.APPROVE_OPTION) {
File source = new File(inputFileChooser.getSelectedFile().getPath());
String filePathInput = source.getAbsolutePath();
if (filePathInput != null) {
// process for the output file path
JFileChooser outputFileChooser = new JFileChooser();
int returnValOutput = outputFileChooser.showSaveDialog(null);
// if the item is approved then may set the path for processing
if (returnValOutput == JFileChooser.APPROVE_OPTION) {
File destination = new File(outputFileChooser
.getSelectedFile().getPath());
String fileNameOut = destination.getAbsolutePath();
if (!fileNameOut.equals(filePathInput)) {
processFile(filePathInput, fileNameOut);
} else {
System.out
.println("input file and output file paths may not be the same");
}
}
}
}
}
/**
Processing the input file to convert special chars to numeric values
(like ALT+178 for superscript 2).
@param inputFilePath
path of the input file
@param outFilePath
path of the output file
*/
public static void processFile(String inputFilePath, String outFilePath) {
ArrayList codeArr = new ArrayList();
readFile(inputFilePath, codeArr);
if (!checkFESTFile(codeArr)) {
System.out
.println("File is not considered a FEST key mapping file");
System.exit(99999);
}
KeyMappingJavaFile keyMappingJavaFile = new KeyMappingJavaFile();
keyMappingJavaFile.addCodeArr(codeArr);
keyMappingJavaFile.convertStrings();
ArrayList outputArr = keyMappingJavaFile.outputStrings();
writeFile(outFilePath, outputArr);
}
/**
Check if the source code being processed is in fact a FEST key stroke
mapping Java class code.
This is a best guess arrangement, where the code is on one line. If the
one line is commented this test does not work.
@param codeArr
code array of the file to convert
@return true is matches basic conditions
*/
private static boolean checkFESTFile(ArrayList codeArr) {
// ASSUMPTION all on the same line
String festTest = "implements KeyStrokeMappingProvider";
for (String codeLine : codeArr) {
if (codeLine.contains(festTest)) {
return true;
}
}
return false;
}
/**
Read a string/text file and place the input into an array list.
@param fileFullPath
absolute file path
@param lineBuf
the array list line buffer
@return true if successful
*/
private static boolean readFile(String fileFullPath,
ArrayList lineBuf) {
// this will read a file and store the lines into an array for
// processing
lineBuf.clear();
BufferedReader inputStream = null;
try {
FileInputStream fis = new FileInputStream(fileFullPath);
InputStreamReader isr = new InputStreamReader(fis, encodingCode);
inputStream = new BufferedReader(isr);
// this inputs each line
String input;
while ((input = inputStream.readLine()) != null) {
// copy the input into an array for processing at leisure
lineBuf.add(input);
}
inputStream.close();
} catch (FileNotFoundException e) {
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
Create a write a file to the file-path with the data provided and
processing and object array that contains strings. (The object array
array may be either a String[] or Object[]-of-string and will work.)
The public overlays for this action support string[] and
ArrayList as input parameters. The design of this code
avoids/minimizes the conversion of either overlay to this method's
parameter using an ArrayCopy or other copying routines; thus providing a
better memory management architecture.)
@param filePath
absolute file path
@param lineOutArr
string array to write
@return true if successful
*/
private static boolean writeFile(String filePath,
ArrayList lineOutArr) {
// the data should be in an array for writing
PrintWriter outputStream = null;
try {
FileOutputStream fos = new FileOutputStream(filePath);
OutputStreamWriter osr = new OutputStreamWriter(fos, encodingCode);
outputStream = new PrintWriter(osr);
for (String strObj : lineOutArr) {
outputStream.println(strObj);
}
outputStream.close();
outputStream = null;
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
if (outputStream != null) {
outputStream.close();
}
}
return true;
}
}
/**
Key mapping provider java code file to be processed.
*/
class KeyMappingJavaFile {
/** the lines of code array as input */
ArrayList fileLineOfCodeArr = new ArrayList();
/**
string of line to add
/**
array list of code lines
/**
/**
Output the converted strings for processing into an array list of
strings.
@return array list of strings
*/
public ArrayList outputStrings() {
ArrayList outputArr = new ArrayList();
for (KeyMappingLineOfCode k : this.fileLineOfCodeArr) {
outputArr.add(k.outputConvertedString());
}
return outputArr;
}
}
/**
Key mapping line of code for a single line with an input line and after
conversion an output line.
*/
class KeyMappingLineOfCode {
/** string for input of code line */
String inputLineStr;
/** string for output of code line */
String outputLineStr;
/**
line of code string
/**
Convert the input code line that meets a special format into the special
character needs necessary for compiling independent of Unicode chars in
single quotes.
mappings.add(mapping('g', VK_G, NO_MASK)); -> mappings.add(mapping('g', VK_G, NO_MASK));
mappings.add(mapping('?', VK_G, NO_MASK)); -> mappings.add(mapping(178, VK_G, NO_MASK));
- a 1st single-quote indicates a line needs to be checked for conversion
- if the char in the single-quotes is not an ASCII, assume a UTF special
character and convert to a numeric value instead of a '?' value
*/
public void convertString4Output() {
CharsetEncoder asciiEncoder = Charset.forName("US-ASCII").newEncoder();
// assumptions only one single-quote in a line for mapping
//
// find the first single quote in the string
int singleQuoteIdx = this.inputLineStr.indexOf("'");
// copy-line-as-is is a boolean that is set if a
// line is not-a-line for conversion
//
// a conversion line would be consider to be:
// - has a single-quote
// - the char after the quote is non-ASCII
//
// mappings.add(mapping('?', VK_G, NO_MASK));
//
// NB: ? is a special char representation for comment purposes
//
boolean copyLineAsIs = true;
if (singleQuoteIdx > -1) {
// have a single-quote
char c2Test = this.inputLineStr.charAt(singleQuoteIdx + 1);
// this is a boolean to force all conversions to be
// applied to a numeric value. DEBUG testing arrangement.
boolean alwaysNonAscii = false;
if (c2Test != '') {
int d = (int) c2Test;
// if this is an ASCII char then the code line has no conversion
// needed to be done
if (!asciiEncoder.canEncode(c2Test) || alwaysNonAscii) {
// convert the char in the quotes to a numeric
//
// mappings.add(mapping('?', VK_G, NO_MASK));
// -> mappings.add(mapping((char)178, VK_G, NO_MASK)); //
// 178 -> ?
//
// NB: ? is a special char representation for comment
// purposes
//
this.outputLineStr = String.format(
ProcessingKeyMapperFESTSwing.conversionFormat,
this.inputLineStr.substring(0, singleQuoteIdx), d,
this.inputLineStr.substring(singleQuoteIdx + 3));
} else {
// no conversion but the numeric maybe useful
this.outputLineStr = this.inputLineStr;
}
// add a comment that provides the numeric and character
// side-by-side
this.outputLineStr = String.format("%s // %d .. %c",
this.outputLineStr, d, c2Test);
copyLineAsIs = false;
}
}
// retain lines as the same due to no conversion need
if (copyLineAsIs) {
this.outputLineStr = this.inputLineStr;
}
}
/**
Output the line in its converted form (maybe not have been converted).
@return string for new line
*/
public String outputConvertedString() {
System.out.println(this.outputLineStr);
return this.outputLineStr;
}
}
When running tests on Mac OS X (10.8.4) and Java 7 (1.7.0_21-b12) the mouse pointer jitters over text fields and takes dozens of seconds before it finally clicks on them. The tests don't really fail but become slow enough to prevent from building.
Emmanuel Puybaret (author of 2 books on Java) found the following workaround. The System property resolution should go in a constant but we favored readability.
org.fest.swing.monitor.WindowStatus
@RunsInEDT
private void mouseMove(final Window w, Point point) {
final int x = point.x;
final int y = point.y;
if (x == 0 || y == 0) return;
robot.mouseMove(x, y);
// ************************
// EP : Dispatch missing MouseEvent under Mac OS X / Java 7
if (System.getProperty("os.name").startsWith("Mac OS X")
&& System.getProperty("java.version").startsWith("1.7")
&& w.isShowing()
&& w.getBounds().contains(x, y)) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
w.dispatchEvent(new java.awt.event.MouseEvent(w, java.awt.event.MouseEvent.MOUSE_MOVED,
System.currentTimeMillis(), 0, x - w.getX(), y - w.getY(), x, y, 0, false, 0));
}
});
}
// EP : End of modification
// ************************
Dimension windowSize = sizeOf(w);
if (windowSize.width > windowSize.height) robot.mouseMove(x + sign, y);
else robot.mouseMove(x, y + sign);
sign = -sign;
}
Hi,
We have a scenario where the window is already opened by other program and we don't no the java call which has opened. Now we need to get that window and we need to do Swing UI testing.Please help.
Thanks
Naren
WE have application in awt applet embedded in html. Will FEST work for that ?
Hi Alex, this is my first contribution to FEST, woohoo :)
Here's the code I'm referring to (in https://github.com/alexruiz/fest-swing-1.x/blob/master/fest-swing/src/main/java/org/fest/swing/driver/JTableHeaderLocation.java):
@RunsInCurrentThread
private String columnName(@Nonnull JTableHeader tableHeader, int index) {
return tableHeader.getTable().getModel().getColumnName(index);
}
columnName(2) would return the name of the column at model index 2. Correct me if I'm wrong, but it should be returning the name of the column at view index 2, which may be different if the view columns have been reordered.
This should fix it:
@RunsInCurrentThread
private String columnName(@Nonnull JTableHeader tableHeader, int index) {
return tableHeader.getTable().getColumnName(index);
}
Probably something Oracle changed. The check for mrj.version returns null on OS X.
Fixing this along with the last 2 issues I submitted enables me to run the test app I wrote for Isssue #2
You may want to change the code as follows as there doesn't appear to be a way to distinguish the OS vs hardware platform and some FEST code relies on isOSX and some on isMacintosh:
isOSX = osName.contains("os x");
isMacintosh = isOSX;
Home page http://fest.easytesting.org/ doesn't work
Using FEST 1.2. Works in Apple's Java 1.6, but not Oracle's Java 1.7.
The issues is that this function depends on the system property "mrj.version" which is not set in Oracle's Java 1.7 for OSX. There is a Java bug on this issue, but it's not marked as fixed until Java 8.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7149564
Because this function returns false, isOSX() also returns false.
I'm not sure what to suggest other than to simply have isMacintosh() and isOSX() simply depend on os.name equal to "OS X" for both checks.
I wish I could provide the exact cause for this but all I can do is state the problem and my workaround.
This is part of a test that has been running for a long time and as part of the migration to Java 7 stopped working (I have a customized build of fest-swing from the code as of Feb 15, 2013).
The test double-clicks on a custom widget to activate it's 'Edit' mode. This will not work with Java 7 / OS X / fest-swing. If I revert to Apple Java 6 the test works. And the original test has been running fine under fest-swing 1.2.1 / Java 6 / OS X for a very long time. Looks like the Oracle Java 7 is the root cause but I have no explanation.
I haven't ruled out that it isn't some quirk with the way our application handles mouse events that is only now coming to light as a result of the Java 7 update.
The old test did the following:
testRobot.doubleClick(wrappedWidget.asJButton())
Now the application registers these as 2 separate mouse pressed events with a click count of 1.
Anyways, I came up with a workaround, which is to send mouse-press events without the intervening mouse-release events. The application registers this as a proper double-click sequence. For what it's worth, here is the workaround:
public void clickCustomWidget(final CustomWidget wrappedWidget, int times) {
final java.awt.Component source = wrappedWidget.asJButton();
final java.awt.Point point = source.getLocationOnScreen();
point.translate(source.getWidth() / 2, source.getHeight() / 2);
testRobot.moveMouse(point);
testRobot.pressMouse(MouseButton.LEFT_BUTTON);
int count = 0;
for (int x = times; x > 1; x--) {
testRobot.pressMouse(MouseButton.LEFT_BUTTON);
awtRobotDelay(200);
}
}
We are hitting this quite frequently, since focus runs on the main thread, it is possible for the focus change to occur between the call to inEdtFocusOwner and the call to FocusMonitor.attachTo(target) in the code below:
private void focus(Component target, boolean wait) {
Component currentOwner = inEdtFocusOwner();
if (currentOwner == target) return;
FocusMonitor focusMonitor = FocusMonitor.attachTo(target);
The result is that focusMonitor never gets a focusGained event since the focus transition has already occurred, and therefore hasFocus returns false even though focus has indeed changed to the target. The timeout loop further down ends up throwing an ActionFailedException "Focus change to X failed"
The fix would be to call inEdtFocusOwner() again after the attachTo call, and if it returns the target, remove the focus listener and return.
I am not sure how to explain this. But I'll try.. Fest slows down to crawl while working with JXTreeTable of swingx. It doesn't slow down initially. It works fine for a while, but after a while when the same actions are repeated it slows down badly.
Here's a video of it slowing down.
http://screencast.com/t/liNttCw2In0w
At times 0.39s to 0.40 a set of operations are performed. These are done when there is one row in the JXTreeTable.
At time 0.49 to end of recording the same operation is repeated but there are now 3 rows in the table, it takes very long for the mouse to click.
I have attached a screenshot taken at the time when fest slows down, which attempts to explain it more
This is the code that does the work:
Step 1) Selecting a node from the tree is done as below:
JTreeFixture folioTreeFixture = importShareholders.panel("treePanel").tree("folioTree");
folioTreeFixture.separator("~");
folioTreeFixture.selectPath(new StringWrapper("Shareholders", true)+"~"+
(ShareType.isEquity(shareType) ? new StringWrapper("Equity Folios", true) : new StringWrapper("Preference Folios", true))+"~"+
new FolioTreeRep(folio.getName(),folioNo, shareType).toString());
Step 2) Searching and selecting a row from the JXTreeTable
int selectRow=-1;
JTableFixture table=importShareholders.table("historyTable");
for(int i=0;i<table.rowCount();i++){
String certificateNumber = table.cell(TableCell.row(i).column(ShareholderHistoryTable.columnIndex(ShareholderHistoryTable.CERT_NO))).value();
String remarks=table.cell(TableCell.row(i).column(ShareholderHistoryTable.columnIndex(ShareholderHistoryTable.REMARKS))).value();
if(StringUtils.isEmpty(remarks) && StringUtils.isNotEmpty(certificateNumber) && Integer.parseInt(certificateNumber)==certNo){
selectRow=i;
break;
}
}
if(selectRow==-1){
fail("Couldn't find certificate number to transfer");
}
return selectRow;
Step 3) Showing the pop up menu and clicking the row
table.showPopupMenuAt(TableCell.row(selectRow).column(0)).menuItem("btnTransfer").click();
I am not sure why its slowing down. Please let me know if there is any more info I can help with. Would be grateful for some help in solving the problem
When you have a custom event queue then any call to waitForIdle will wait until the idleTimeout because the following:
while (eventQueue.peekEvent() != null)
peekEvent returns an InvocationEvent caused by a timer blinking the caret in the textfield.
Here is a testcase that illustrates the issue:
package org.fest.swing.core;
import org.fest.swing.test.recorder.KeyRecorder;
import org.fest.swing.timing.Condition;
import org.junit.After;
import org.junit.Test;
import java.awt.*;
import java.util.concurrent.Executors;
import static java.awt.event.KeyEvent.*;
import static org.fest.swing.timing.Pause.pause;
import static org.fest.swing.timing.Timeout.timeout;
import static org.fest.util.Arrays.array;
/**
* Tests for issue with slow waitForIdle with a custom event queue
*
* @author Glen Schrader
* @author Alex Ruiz
*/
public class CustomEventQueue_Test extends BasicRobot_TestCase {
private CustomEventQueue newEventQueue = new CustomEventQueue();
@Override
void beforeShowingWindow() {
Toolkit.getDefaultToolkit().getSystemEventQueue().push(newEventQueue);
}
@After
public void cleanup() {
newEventQueue.remove();
}
@Test
public void type_keys_before_timeout() {
giveFocusToTextField();
final KeyRecorder recorder = KeyRecorder.attachTo(window.textField);
Executors.newSingleThreadExecutor().execute(new Runnable() {
public void run() {
robot.pressAndReleaseKeys(VK_A, VK_B, VK_C);
}
});
pause(new Condition("until all keys are typed") {
@Override
public boolean test() {
Integer[] expectedKeys = array(VK_A, VK_B, VK_C);
return recorder.keysWerePressed(expectedKeys) && recorder.keysWereReleased(expectedKeys);
}
}, timeout(1000));
}
private class CustomEventQueue extends EventQueue {
protected void dispatchEvent(final AWTEvent event) {
super.dispatchEvent(event);
}
public void remove() {
pop();
}
}
}
As discussed at https://groups.google.com/d/msg/easytesting/bAt1nWx55FM/CPbXguc3whQJ
Would be nice to include the following code to throw a RuntimeException if the Java vendor is obviously not Oracle.
if (!System.getProperty("java.vendor").toLowerCase().contains("oracle"))
{
throw new RuntimeException("Can only install FailOnThreadViolationRepaintManager on Oracle JVMs");
}
The click() method in JMenuItemDriver is not being called because it doesn't override correctly. Adding the following method fixes the problem, but I don't know how that solution fits with your best practices. FWIW....
@RunsInEDT
public void click(@Nonnull Component menuItem) {
click((JMenuItem) menuItem);
}
When I test using findActivePopup I found that JPopupMenu with a cascade menu fails to found a popup.
On investigation (using FEST-Swing source code and debug via eclipse) the method private JPopupMenu activePopupMenu() of BasicRobot.java was doing a finder action and the found List structure had more than one item (JPopupMenu, JMenu). Thus the test for found.size() == 1 was failing. Changing the test to >= 1 resolved the problem.
Any chance this can be put into the new release of FEST-Swing?
Below is the code and a JUnit test for testing with a cascade.
@RunsInEDT
private JPopupMenu activePopupMenu() {
List found = new ArrayList(finder().findAll(POPUP_MATCHER));
if (found.size() == 1) return (JPopupMenu)found.get(0);
return null;
}
advise to change to >= from == as the finder seems to find additional cascade jmenu in the array too
@RunsInEDT
private JPopupMenu activePopupMenu() {
List found = new ArrayList(finder().findAll(POPUP_MATCHER));
if (found.size() >= 1) return (JPopupMenu)found.get(0);
return null;
}
@RunsInEDT
final JPopupMenu addPopupMenuToTextFieldWithCascade() {
return createAndSetPopupMenuWithCascade(window.textField, "Luke", "Leia");
}
@RunsInEDT
public static JPopupMenu createAndSetPopupMenuWithCascade(final JComponent c, final String...items) {
return execute(new GuiQuery() {
@OverRide protected JPopupMenu executeInEDT() {
JPopupMenu popupMenu = new JPopupMenu();
JMenu menu2 = new JMenu("cascade test");
menu2.add(new JMenuItem("cascade line 1"));
menu2.add(new JMenuItem("cascade line 2"));
popupMenu.add(menu2);
popupMenu.add(new JMenuItem(items[0]));
popupMenu.add(menu2);
popupMenu.add(new JMenuItem(items[1]));
c.setComponentPopupMenu(popupMenu); // causes popup-menu to display
return popupMenu;
}
});
}
@test
public void should_return_active_popupMenu_cascadingPopup() {
addPopupMenuToTextFieldWithCascade();
robot.showPopupMenu(window.textField);
// wait for 2nd cascade menu to show
pause(1000);
JPopupMenu found = robot.findActivePopupMenu();
MenuElement[] meArr = found.getSubElements();
Component comp = meArr[0].getComponent();
assertThat("cascade line 1").isEqualTo(((JMenuItem)comp).getText());
}
Putting a dependency on fest-swing causes compile error:
compile 'org.easytesting:fest-swing:1.2a4'
Causes the following build error:
Failed testing : test.DocTest#setUpOnce
java.lang.NoSuchMethodError: org.fest.util.Strings.isEmpty(Ljava/lang/String;)Z
test.DocTest.setUpOnce FAILED
java.lang.NoSuchMethodError at DocTest.java:83
Is it the same issue as https://jira.codehaus.org/browse/FEST-482 ?
In that case, it should be considered as priority as it makes it impossible to use it.
Is there any tool available to spy any Java Swing apps in order to get GUI fields object properties?
I create a textField ti input file path.
final JTextField filePathField = new JTextField(20);
filePathField.setName(name);
filePathField.serVisible(false)
so it's not shown at beginning.
Then I use a change button to show it.
changeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
...
filePathField.setVisible(true);
...
}
});
Other select button will get text from filePathField.
selectButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
...
String filePath = filePathField.getText().trim();
...
}
});
My test code:
changeButton.click();
// filePathField will show after changeButton clicked.
filePathField.setText(TEST_FILES + "a.log");
selectButton.click(); -> I found this action will not really do, if I System.out.println("xxxxx"), it will not shown in console
But If I set filePathField.serVisible(true) in codes, test goes OK.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.