--- old/src/org/netbeans/jemmy/WindowWaiter.java 2017-09-06 09:31:27.000000000 -0700 +++ new/src/org/netbeans/jemmy/WindowWaiter.java 2017-09-06 09:31:27.000000000 -0700 @@ -25,6 +25,7 @@ import java.awt.Component; import java.awt.Frame; import java.awt.Window; +import java.util.stream.Stream; /** * A WindowWaiter is a utility class used to look or wait for Windows. It @@ -282,6 +283,91 @@ return waitWindow(o, ch, 0); } + /** + * Wait till the count of windows which meet the the search criteria becomes + * equal to count. + * + * @param ch a component chooser used to define and apply the search + * criteria. + * @param count the number of expected windows meeting the search criteria. + * @throws InterruptedException + */ + public static void waitWindowCount(ComponentChooser ch, int count) + throws InterruptedException { + waitWindowCount(null, ch, count); + } + + /** + * Wait till the count of windows which meet the the search criteria becomes + * equal to count. + * + * @param owner The owner window of all the windows to be checked + * @param ch a component chooser used to define and apply the search + * criteria. + * @param count the number of expected windows meeting the search criteria. + * @throws InterruptedException + */ + public static void waitWindowCount(Window owner, ComponentChooser ch, int count) + throws InterruptedException { + Waiter stateWaiter = new Waiter<>(new Waitable() { + @Override + public String actionProduced(Void obj) { + return countWindows(owner, ch) == count ? "" : null; + } + + @Override + public String getDescription() { + return "Wait till the count of windows matching the criteria " + + "specified by ComponentChooser reaches :" + count; + } + + @Override + public String toString() { + return "Operator.waitState.Waitable{description = " + + getDescription() + '}'; + } + }); + stateWaiter.waitAction(null); + } + + /** + * Counts all the windows owned by the owner window which match the + * criterion specified by component chooser. + * + * @param owner The owner window of all the windows to be checked + * @param ch A component chooser used to define and apply the search + * criteria + * @return the number of matched windows + */ + public static int countWindows(Window owner, ComponentChooser ch) { + return new QueueTool().invokeAndWait(new QueueTool.QueueAction(null) { + + @Override + public Integer launch() { + Window[] windows; + if (owner == null) { + windows = Window.getWindows(); + } else { + windows = owner.getOwnedWindows(); + } + return (int) Stream.of(windows) + .filter(x -> ch.checkComponent(x)).count(); + } + }); + } + + /** + * Counts all the windows which match the criterion specified by component + * chooser. + * + * @param ch A component chooser used to define and apply the search + * criteria + * @return the number of matched windows + */ + public static int countWindows(ComponentChooser ch) { + return countWindows(null, ch); + } + @Override public String getDescription() { return chooser.getDescription(); --- old/src/org/netbeans/jemmy/drivers/menus/QueueJMenuDriver.java 2017-09-06 09:31:27.000000000 -0700 +++ new/src/org/netbeans/jemmy/drivers/menus/QueueJMenuDriver.java 2017-09-06 09:31:27.000000000 -0700 @@ -132,10 +132,9 @@ } }; } - System.err.println("QueueJMenuDriver WORKAROUND 2"); queueTool.waitEmpty(10); queueTool.waitEmpty(10); -// queueTool.waitEmpty(10); + queueTool.waitEmpty(10); result = runAction(action, oper, oper.getTimeouts().getTimeout("ComponentOperator.WaitComponentTimeout"), (chooser instanceof DescriptablePathChooser) --- old/src/org/netbeans/jemmy/drivers/windows/DefaultFrameDriver.java 2017-09-06 09:31:28.000000000 -0700 +++ new/src/org/netbeans/jemmy/drivers/windows/DefaultFrameDriver.java 2017-09-06 09:31:28.000000000 -0700 @@ -22,9 +22,7 @@ */ package org.netbeans.jemmy.drivers.windows; -import java.awt.Dimension; import java.awt.Frame; -import java.awt.Toolkit; import java.awt.Window; import java.awt.event.WindowEvent; @@ -61,16 +59,28 @@ ((FrameOperator) oper).setState(Frame.NORMAL); } + /** Maximizes the frame. + * + * @param oper Frame operator. + * @throws UnsupportedOperatorException if operator class name is not in + * the list of supported classes names + */ @Override public void maximize(ComponentOperator oper) { checkSupported(oper); - oper.setLocation(0, 0); - Dimension ssize = Toolkit.getDefaultToolkit().getScreenSize(); - oper.setSize(ssize.width, ssize.height); + ((FrameOperator) oper).setExtendedState(Frame.MAXIMIZED_BOTH); } + /** Demaximizes the frame. + * + * @param oper Frame operator. + * @throws UnsupportedOperatorException if operator class name is not in + * the list of supported classes names + */ @Override public void demaximize(ComponentOperator oper) { checkSupported(oper); + ((FrameOperator) oper).setExtendedState(Frame.NORMAL); } + } --- old/src/org/netbeans/jemmy/operators/ComponentOperator.java 2017-09-06 09:31:28.000000000 -0700 +++ new/src/org/netbeans/jemmy/operators/ComponentOperator.java 2017-09-06 09:31:28.000000000 -0700 @@ -57,6 +57,8 @@ import java.util.Hashtable; import java.util.Locale; +import static java.lang.Math.abs; + import org.netbeans.jemmy.CharBindingMap; import org.netbeans.jemmy.ComponentChooser; import org.netbeans.jemmy.ComponentSearcher; @@ -1137,6 +1139,87 @@ } /** + * Wait till the Size of the component becomes as expected. + * + * @param exactSize the exact expected size. + */ + public void waitComponentSize(Dimension exactSize) { + waitComponentSize(exactSize, exactSize); + } + + /** + * Wait till the Size of the component becomes between minSize and maxSize. + * + * @param minSize the minimum allowed size. + * @param maxSize the maximum allowed size. + */ + public void waitComponentSize(Dimension minSize, Dimension maxSize) { + waitState(new ComponentChooser() { + @Override + public boolean checkComponent(Component comp) { + Dimension componentSize = comp.getSize(); + return componentSize.height >= minSize.height + && componentSize.height <= maxSize.height + && componentSize.width >= minSize.width + && componentSize.width <= maxSize.width; + } + + @Override + public String getDescription() { + return "Component Size becomes between: " + minSize + + "and " + maxSize; + } + + @Override + public String toString() { + return "ComponentOperator.waitComponentSize" + + ".Waitable{description = " + getDescription() + '}'; + } + }); + } + + /** + * Wait till the component reaches exact location. + * + * @param exactlocation exact expected location. + */ + public void waitComponentLocation(Point exactlocation) { + waitComponentLocation(exactlocation, exactlocation); + } + + /** + * Wait till the component reaches location between minLocation and + * maxLocation + * + * @param minLocation minimum expected location. + * @param maxLocation maximum expected location. + */ + public void waitComponentLocation(Point minLocation, Point maxLocation) { + waitState(new ComponentChooser() { + @Override + public boolean checkComponent(Component comp) { + Point componentLocation = comp.getLocation(); + return componentLocation.x >= minLocation.x + && componentLocation.x <= maxLocation.x + && componentLocation.y >= minLocation.y + && componentLocation.y <= maxLocation.y; + } + + @Override + public String getDescription() { + return "Component reaches location between :" + minLocation + + "and " + maxLocation; + } + + @Override + public String toString() { + return "ComponentOperator.waitComponentLocation" + + ".Waitable{description = " + getDescription() + '}'; + } + }); + } + + /** * Returns information about component. */ @Override --- old/src/org/netbeans/jemmy/operators/FrameOperator.java 2017-09-06 09:31:28.000000000 -0700 +++ new/src/org/netbeans/jemmy/operators/FrameOperator.java 2017-09-06 09:31:28.000000000 -0700 @@ -30,7 +30,6 @@ import org.netbeans.jemmy.ComponentChooser; import org.netbeans.jemmy.FrameWaiter; -import org.netbeans.jemmy.JemmyException; import org.netbeans.jemmy.JemmyProperties; import org.netbeans.jemmy.Outputable; import org.netbeans.jemmy.TestOut; @@ -275,7 +274,7 @@ output.printGolden("Maximizing frame"); driver.maximize(this); if (getVerification()) { - waitState(Frame.NORMAL); + waitState(Frame.MAXIMIZED_BOTH); } } @@ -307,7 +306,7 @@ waitState(new ComponentChooser() { @Override public boolean checkComponent(Component comp) { - return ((Frame) comp).getState() == state; + return ((Frame) comp).getExtendedState() == state; } @Override @@ -377,6 +376,19 @@ } /** + * Maps {@code Frame.getExtendedState()} through queue + * @return the state of the frame + */ + public int getExtendedState() { + return (runMapping(new MapAction("getExtendedState") { + @Override + public Integer map() { + return ((Frame) getSource()).getExtendedState(); + } + })); + } + + /** * Maps {@code Frame.getTitle()} through queue */ public String getTitle() { @@ -449,6 +461,21 @@ } /** + * Maps {@code Frame.setExtendedState(int)} through queue + * @param state of the frame + */ + public void setExtendedState(final int state) { + runMapping(new MapAction("setExtendedState") { + @Override + public Void map() { + ((Frame) getSource()).setExtendedState(state); + return null; + } + }); + + } + + /** * Maps {@code Frame.setTitle(String)} through queue */ public void setTitle(final String string) { @@ -481,7 +508,8 @@ waiter.setOutput(output); return waiter.waitFrame(new FrameFinder(chooser), index); } catch (InterruptedException e) { - throw new JemmyException("Interrupted while waiting for a frame with " + chooser + " and index = " + index, e); + throw new JemmyException("Interrupted while waiting for a frame with " + + chooser + " and index = " + index, e); } } --- old/src/org/netbeans/jemmy/operators/JFrameOperator.java 2017-09-06 09:31:29.000000000 -0700 +++ new/src/org/netbeans/jemmy/operators/JFrameOperator.java 2017-09-06 09:31:29.000000000 -0700 @@ -103,7 +103,9 @@ * */ public JFrameOperator(String title, int index, Operator env) { - this(new FrameByTitleFinder(title, env.getComparator()), index, env); + this(new JFrameFinder(new FrameByTitleFinder(title, + env.getComparator())), + index, env); } /** --- old/src/org/netbeans/jemmy/operators/JSpinnerOperator.java 2017-09-06 09:31:29.000000000 -0700 +++ new/src/org/netbeans/jemmy/operators/JSpinnerOperator.java 2017-09-06 09:31:29.000000000 -0700 @@ -28,7 +28,6 @@ import java.util.Date; import java.util.Hashtable; import java.util.List; -import java.util.Objects; import javax.swing.JComponent; import javax.swing.JSpinner; @@ -967,7 +966,7 @@ /** * Abstract class for a scrolling of a spinner having unknown model type. A - * subclass needs to override {@code equals(Object)} value to specify a + * subclass needs to override {@code reached(Object)} method to specify a * criteria of successful scrolling. */ public abstract static class ObjectScrollAdjuster implements ScrollAdjuster { @@ -989,7 +988,7 @@ @Override public int getScrollDirection() { - if (equals(model.getValue())) { + if (reached(model.getValue())) { return ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION; } else if (direction == ScrollAdjuster.INCREASE_SCROLL_DIRECTION && model.getNextValue() != null @@ -1001,7 +1000,7 @@ } } - public abstract boolean equals(Object curvalue); + public abstract boolean reached(Object curvalue); @Override public int getScrollOrientation() { @@ -1029,15 +1028,9 @@ this.obj = obj; } - public boolean equals(Object curvalue) { - return curvalue != null && curvalue.equals(obj); - } - @Override - public int hashCode() { - int hash = 7; - hash = 79 * hash + Objects.hashCode(this.obj); - return hash; + public boolean reached(Object curvalue) { + return curvalue != null && curvalue.equals(obj); } @Override @@ -1093,18 +1086,9 @@ this(oper, pattern, oper.getComparator(), direction); } - public boolean equals(Object curvalue) { - - // TODO: This abuses the semantics of Object.equals() - return curvalue != null && comparator.equals(curvalue.toString(), pattern); - } - @Override - public int hashCode() { - int hash = 7; - hash = 97 * hash + Objects.hashCode(this.pattern); - hash = 97 * hash + Objects.hashCode(this.comparator); - return hash; + public boolean reached(Object curvalue) { + return curvalue != null && comparator.equals(curvalue.toString(), pattern); } @Override