blob: 3ca7c5408cd468e0a4aad3cee931deb3860dec72 [file] [log] [blame]
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.netbeans.jemmy;
import java.awt.Component;
import java.awt.Frame;
/**
*
* Contains methods to search and wait Frame. A FrameWaiter is a utility class
* used to look or wait for Frames. It contains methods to search for a Frame
* among the currently showing Frames as well as methods that wait for a Frame
* to show within an allotted time period.
*
* <BR><BR>Timeouts used: <BR>
* FrameWaiter.WaitFrameTimeout - time to wait frame displayed. <BR>
* FrameWaiter.AfterFrameTimeout - time to sleep after frame has been displayed.
* <BR>
*
* @see org.netbeans.jemmy.Timeouts
*
* @author Alexandre Iline (alexandre.iline@oracle.com)
*/
public class FrameWaiter extends WindowWaiter implements Timeoutable, Outputable {
private final static long WAIT_TIME = 60000;
private final static long AFTER_WAIT_TIME = 0;
private Timeouts timeouts;
private TestOut output;
/**
* Constructor.
*/
public FrameWaiter() {
super();
setTimeouts(JemmyProperties.getProperties().getTimeouts());
setOutput(JemmyProperties.getProperties().getOutput());
}
/**
* Searches for a Frame. Search among the currently showing Frames for one
* that meets the search criteria applied by the
* {@code ComponentChooser} parameter.
*
* @param cc A component chooser used to define and apply the search
* criteria.
* @return a reference to the first Frame that is showing and that meets the
* search criteria. If no such Frame can be found, a {@code null}
* reference is returned.
*/
public static Frame getFrame(ComponentChooser cc) {
return (Frame) WindowWaiter.getWindow(new FrameSubChooser(cc));
}
/**
* Searches for a Frame. The search proceeds among the currently showing
* Frames for the {@code index+1}'th Frame that meets the criteria
* defined and applied by the {@code ComonentChooser} parameter.
*
* @param cc A component chooser used to define and apply the search
* criteria.
* @param index The ordinal index of the Frame in the set of currently
* displayed Frames. The first index is 0.
* @return a reference to the {@code index+1}'th Frame that is showing
* and that meets the search criteria. If there are fewer than
* {@code index+1} Frames, a {@code null} reference is returned.
*/
public static Frame getFrame(ComponentChooser cc, int index) {
return (Frame) WindowWaiter.getWindow(new FrameSubChooser(cc), index);
}
/**
* Searches for a Frame by title. The search proceeds among the currently
* showing Frames for the first with a suitable title.
*
* @param title Frame title or subtitle.
* @param ce If {@code true} and the search is case sensitive, then a
* match occurs when the {@code title} argument is a substring of a
* Frame title. If {@code false} and the search is case sensitive, then
* the {@code title} argument and the Frame title must be the same. If
* {@code true} and the search is case insensitive, then a match occurs
* when the {@code title} argument is a substring of the Frame title
* after changing both to upper case. If {@code false} and the search
* is case insensitive, then a match occurs when the {@code title}
* argument is a substring of the Frame title after changing both to upper
* case.
* @param cc If {@code true} the search is case sensitive; otherwise,
* the search is case insensitive.
* @return a reference to the first Frame that is showing and that has a
* suitable title. If no such Frame can be found, a {@code null}
* reference is returned.
*/
public static Frame getFrame(String title, boolean ce, boolean cc) {
return (Frame) WindowWaiter.getWindow(new FrameByTitleChooser(title, ce, cc));
}
/**
* Searches for a Frame by title. The search is for the
* {@code index+1}'th Frame among the currently showing Frames that
* possess a suitable title.
*
* @param title Frame title or subtitle.
* @param ce If {@code true} and the search is case sensitive, then a
* match occurs when the {@code title} argument is a substring of a
* Frame title. If {@code false} and the search is case sensitive, then
* the {@code title} argument and the Frame title must be the same. If
* {@code true} and the search is case insensitive, then a match occurs
* when the {@code title} argument is a substring of the Frame title
* after changing both to upper case. If {@code false} and the search
* is case insensitive, then a match occurs when the {@code title}
* argument is a substring of the Frame title after changing both to upper
* case.
* @param cc If {@code true} the search is case sensitive; otherwise,
* the search is case insensitive.
* @param index The ordinal index of the Frame in the set of currently
* displayed Frames. The first index is 0.
* @return a reference to the {@code index+1}'th Frame that is showing
* and that has a suitable title. If there are fewer than
* {@code index+1} Frames, a {@code null} reference is returned.
*/
public static Frame getFrame(String title, boolean ce, boolean cc, int index) {
return (Frame) WindowWaiter.getWindow(new FrameByTitleChooser(title, ce, cc), index);
}
static {
Timeouts.initDefault("FrameWaiter.WaitFrameTimeout", WAIT_TIME);
Timeouts.initDefault("FrameWaiter.AfterFrameTimeout", AFTER_WAIT_TIME);
}
/**
* Defines current timeouts.
*
* @param timeouts A collection of timeout assignments.
* @see org.netbeans.jemmy.Timeoutable
* @see org.netbeans.jemmy.Timeouts
* @see #getTimeouts
*/
@Override
public void setTimeouts(Timeouts timeouts) {
this.timeouts = timeouts;
Timeouts times = timeouts.cloneThis();
times.setTimeout("WindowWaiter.WaitWindowTimeout",
timeouts.getTimeout("FrameWaiter.WaitFrameTimeout"));
times.setTimeout("WindowWaiter.AfterWindowTimeout",
timeouts.getTimeout("FrameWaiter.AfterFrameTimeout"));
super.setTimeouts(times);
}
/**
* Return current timeouts.
*
* @return the collection of current timeout assignments.
* @see org.netbeans.jemmy.Timeoutable
* @see org.netbeans.jemmy.Timeouts
* @see #setTimeouts
*/
@Override
public Timeouts getTimeouts() {
return timeouts;
}
/**
* Defines print output streams or writers.
*
* @param output Identify the streams or writers used for print output.
* @see org.netbeans.jemmy.Outputable
* @see org.netbeans.jemmy.TestOut
* @see #getOutput
*/
@Override
public void setOutput(TestOut output) {
this.output = output;
super.setOutput(output);
}
/**
* Returns print output streams or writers.
*
* @return an object that contains references to objects for printing to
* output and err streams.
* @see org.netbeans.jemmy.Outputable
* @see org.netbeans.jemmy.TestOut
* @see #setOutput
*/
@Override
public TestOut getOutput() {
return output;
}
/**
* Waits for a Frame to show. Wait for the {@code index+1}'th Frame
* that meets the criteria defined and applied by the
* {@code ComonentChooser} parameter to show up.
*
* @param ch A component chooser used to define and apply the search
* criteria.
* @param index The ordinal index of the Frame in the set of currently
* displayed Frames. The first index is 0.
* @return a reference to the {@code index+1}'th Frame that shows and
* that meets the search criteria. If fewer than {@code index+1} Frames
* show up in the allotted time period then a {@code null} reference is
* returned.
* @throws TimeoutExpiredException
* @see org.netbeans.jemmy.WindowWaiter#actionProduced(Object)
* @exception InterruptedException
*/
public Frame waitFrame(ComponentChooser ch, int index)
throws InterruptedException {
setTimeouts(timeouts);
return (Frame) waitWindow(new FrameSubChooser(ch), index);
}
/**
* Waits for a Frame to show. Wait for a Frame that meets the search
* criteria applied by the {@code ComponentChooser} parameter to show
* up.
*
* @param ch A component chooser used to define and apply the search
* criteria.
* @return a reference to the first Frame that shows and that meets the
* search criteria. If no such Frame can be found within the time period
* allotted, a {@code null} reference is returned.
* @throws TimeoutExpiredException
* @see org.netbeans.jemmy.WindowWaiter#actionProduced(Object)
* @exception InterruptedException
*/
public Frame waitFrame(ComponentChooser ch)
throws InterruptedException {
return waitFrame(ch, 0);
}
/**
* Waits for a Frame to show. Wait for the {@code index+1}'th Frame to
* show with a suitable title.
*
* @param title Frame title or subtitle.
* @param compareExactly If {@code true} and the search is case
* sensitive, then a match occurs when the {@code title} argument is a
* substring of a Frame title. If {@code false} and the search is case
* sensitive, then the {@code title} argument and the Frame title must
* be the same. If {@code true} and the search is case insensitive,
* then a match occurs when the {@code title} argument is a substring
* of the Frame title after changing both to upper case. If
* {@code false} and the search is case insensitive, then a match
* occurs when the {@code title} argument is a substring of the Frame
* title after changing both to upper case.
* @param compareCaseSensitive If {@code true} the search is case
* sensitive; otherwise, the search is case insensitive.
* @param index The ordinal index of the Frame in the set of currently
* displayed Frames with the proper window ownership and a suitable title.
* The first index is 0.
* @return a reference to the {@code index+1}'th Frame to show and that
* has a suitable title. If no such Frame can be found within the time
* period allotted, a {@code null} reference is returned.
* @throws TimeoutExpiredException
* @see org.netbeans.jemmy.WindowWaiter#actionProduced(Object)
* @exception InterruptedException
*/
public Frame waitFrame(String title, boolean compareExactly, boolean compareCaseSensitive, int index)
throws InterruptedException {
return waitFrame(new FrameByTitleChooser(title, compareExactly, compareCaseSensitive), index);
}
/**
* Waits for a Frame to show. Wait for the first Frame to show with a
* suitable title.
*
* @param title Frame title or subtitle.
* @param compareExactly If {@code true} and the search is case
* sensitive, then a match occurs when the {@code title} argument is a
* substring of a Frame title. If {@code false} and the search is case
* sensitive, then the {@code title} argument and the Frame title must
* be the same. If {@code true} and the search is case insensitive,
* then a match occurs when the {@code title} argument is a substring
* of the Frame title after changing both to upper case. If
* {@code false} and the search is case insensitive, then a match
* occurs when the {@code title} argument is a substring of the Frame
* title after changing both to upper case.
* @param compareCaseSensitive If {@code true} the search is case
* sensitive; otherwise, the search is case insensitive.
* @return a reference to the first Frame to show and that has a suitable
* title. If no such Frame can be found within the time period allotted, a
* {@code null} reference is returned.
* @throws TimeoutExpiredException
* @see org.netbeans.jemmy.WindowWaiter#actionProduced(Object)
* @exception InterruptedException
*/
public Frame waitFrame(String title, boolean compareExactly, boolean compareCaseSensitive)
throws InterruptedException {
return waitFrame(title, compareExactly, compareCaseSensitive, 0);
}
/**
* @see Waiter#getWaitingStartedMessage()
*/
@Override
protected String getWaitingStartedMessage() {
return "Start to wait frame \"" + getComponentChooser().getDescription() + "\" opened";
}
/**
* Overrides WindowWaiter.getTimeoutExpiredMessage. Returns the timeout
* expired message value.
*
* @param timeSpent Time spent for waiting
* @return a message tring
* @see Waiter#getTimeoutExpiredMessage(long)
*/
@Override
protected String getTimeoutExpiredMessage(long timeSpent) {
return ("Frame \"" + getComponentChooser().getDescription() + "\" has not been opened in "
+ timeSpent + " milliseconds");
}
/**
* Overrides WindowWaiter.getActionProducedMessage. Returns the action
* produced message value.
*
* @param timeSpent Time spent for waiting.
* @param result A message string.
* @return a message tring
* @see Waiter#getActionProducedMessage(long, Object)
*/
@Override
protected String getActionProducedMessage(long timeSpent, final Object result) {
String resultToString = null;
if (result instanceof Component) {
// run toString in dispatch thread
resultToString = new QueueTool().invokeSmoothly(
new QueueTool.QueueAction<String>("result.toString()") {
@Override
public String launch() {
return result.toString();
}
}
);
} else {
resultToString = result.toString();
}
return ("Frame \"" + getComponentChooser().getDescription() + "\" has been opened in "
+ timeSpent + " milliseconds"
+ "\n " + resultToString);
}
/**
* @see Waiter#getGoldenWaitingStartedMessage()
*/
@Override
protected String getGoldenWaitingStartedMessage() {
return "Start to wait frame \"" + getComponentChooser().getDescription() + "\" opened";
}
/**
* @see Waiter#getGoldenTimeoutExpiredMessage()
*/
@Override
protected String getGoldenTimeoutExpiredMessage() {
return "Frame \"" + getComponentChooser().getDescription() + "\" has not been opened";
}
/**
* @see Waiter#getGoldenActionProducedMessage()
*/
@Override
protected String getGoldenActionProducedMessage() {
return "Frame \"" + getComponentChooser().getDescription() + "\" has been opened";
}
private static class FrameSubChooser implements ComponentChooser {
private ComponentChooser chooser;
public FrameSubChooser(ComponentChooser c) {
super();
chooser = c;
}
@Override
public boolean checkComponent(Component comp) {
if (comp instanceof Frame) {
return ((FIND_INVISIBLE_WINDOWS || (comp.isShowing() && comp.isVisible()))
&& chooser.checkComponent(comp));
} else {
return false;
}
}
@Override
public String getDescription() {
return chooser.getDescription();
}
@Override
public String toString() {
return "FrameSubChooser{" + "chooser=" + chooser + '}';
}
}
private static class FrameByTitleChooser implements ComponentChooser {
String title;
boolean compareExactly;
boolean compareCaseSensitive;
public FrameByTitleChooser(String t, boolean ce, boolean cc) {
super();
title = t;
compareExactly = ce;
compareCaseSensitive = cc;
}
@Override
public boolean checkComponent(Component comp) {
if (comp instanceof Frame) {
if ((FIND_INVISIBLE_WINDOWS || (comp.isShowing() && comp.isVisible()))
&& ((Frame) comp).getTitle() != null) {
String titleToComp = ((Frame) comp).getTitle();
String contextToComp = title;
if (compareCaseSensitive) {
titleToComp = titleToComp.toUpperCase();
contextToComp = contextToComp.toUpperCase();
}
if (compareExactly) {
return titleToComp.equals(contextToComp);
} else {
return titleToComp.contains(contextToComp);
}
}
}
return false;
}
@Override
public String getDescription() {
return title;
}
@Override
public String toString() {
return "FrameByTitleChooser{" + "title=" + title + ", compareExactly=" + compareExactly + ", compareCaseSensitive=" + compareCaseSensitive + '}';
}
}
}