blob: f61f926aa16c7b3f7026f9e115e59f4b5693aa6e [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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.operators;
import java.awt.Component;
import java.awt.Container;
import java.awt.TextComponent;
import java.awt.event.TextListener;
import java.util.Hashtable;
import org.netbeans.jemmy.Action;
import org.netbeans.jemmy.ComponentChooser;
import org.netbeans.jemmy.Outputable;
import org.netbeans.jemmy.TestOut;
import org.netbeans.jemmy.Timeoutable;
import org.netbeans.jemmy.Timeouts;
import org.netbeans.jemmy.drivers.DriverManager;
import org.netbeans.jemmy.drivers.TextDriver;
/**
* This operator type covers java.awt.TextArea component.
*
*
* @see org.netbeans.jemmy.Timeouts
*
* @author Alexandre Iline (alexandre.iline@oracle.com)
*
*/
public class TextComponentOperator extends ComponentOperator
implements Timeoutable, Outputable {
/**
* Identifier for a "text" property.
*
* @see #getDump
*/
public static final String TEXT_DPROP = "Text";
private final static long PUSH_KEY_TIMEOUT = 0;
private final static long BETWEEN_KEYS_TIMEOUT = 0;
private final static long CHANGE_CARET_POSITION_TIMEOUT = 60000;
private final static long TYPE_TEXT_TIMEOUT = 60000;
private Timeouts timeouts;
private TestOut output;
private TextDriver driver;
/**
* Constructor.
*
* @param b The {@code java.awt.TextComponent} managed by this
* instance.
*/
public TextComponentOperator(TextComponent b) {
super(b);
driver = DriverManager.getTextDriver(getClass());
}
/**
* Constructs a TextComponentOperator object.
*
* @param cont a container
* @param chooser a component chooser specifying searching criteria.
* @param index an index between appropriate ones.
*/
public TextComponentOperator(ContainerOperator<?> cont, ComponentChooser chooser, int index) {
this((TextComponent) cont.
waitSubComponent(new TextComponentFinder(chooser),
index));
copyEnvironment(cont);
}
/**
* Constructs a TextComponentOperator object.
*
* @param cont a container
* @param chooser a component chooser specifying searching criteria.
*/
public TextComponentOperator(ContainerOperator<?> cont, ComponentChooser chooser) {
this(cont, chooser, 0);
}
/**
* Constructor. Waits for a component in a container to show. The component
* is identified as the {@code index+1}'th
* {@code java.awt.TextComponent} that shows, lies below the container
* in the display containment hierarchy, and that has the desired text. Uses
* cont's timeout and output for waiting and to init this operator.
*
* @param cont The operator for a container containing the sought for
* textComponent.
* @param text TextComponent text.
* @param index Ordinal component index. The first component has
* {@code index} 0.
* @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
*/
public TextComponentOperator(ContainerOperator<?> cont, String text, int index) {
this((TextComponent) waitComponent(cont,
new TextComponentByTextFinder(text,
cont.getComparator()),
index));
copyEnvironment(cont);
}
/**
* Constructor. Waits for a component in a container to show. The component
* is identified as the first {@code java.awt.TextComponent} that
* shows, lies below the container in the display containment hierarchy, and
* that has the desired text. Uses cont's timeout and output for waiting and
* to init this operator.
*
* @param cont The operator for a container containing the sought for
* textComponent.
* @param text TextComponent text.
* @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
*/
public TextComponentOperator(ContainerOperator<?> cont, String text) {
this(cont, text, 0);
}
/**
* Constructor. Waits component in container first. Uses cont's timeout and
* output for waiting and to init operator.
*
* @param cont The operator for a container containing the sought for
* textComponent.
* @param index Ordinal component index.
* @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
*/
public TextComponentOperator(ContainerOperator<?> cont, int index) {
this((TextComponent) waitComponent(cont,
new TextComponentFinder(),
index));
copyEnvironment(cont);
}
/**
* Constructor. Waits component in container first. Uses cont's timeout and
* output for waiting and to init operator.
*
* @param cont The operator for a container containing the sought for
* textComponent.
* @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
*/
public TextComponentOperator(ContainerOperator<?> cont) {
this(cont, 0);
}
/**
* Searches TextComponent in a container.
*
* @param cont Container in which to search for the component. The container
* lies above the component in the display containment hierarchy. The
* containment need not be direct.
* @param chooser org.netbeans.jemmy.ComponentChooser implementation,
* defining and applying search criteria.
* @param index Ordinal component index. The first {@code index} is 0.
* @return TextComponent instance or null if component was not found.
*/
public static TextComponent findTextComponent(Container cont, ComponentChooser chooser, int index) {
return (TextComponent) findComponent(cont, new TextComponentFinder(chooser), index);
}
/**
* Searches for the first TextComponent in a container.
*
* @param cont Container in which to search for the component. The container
* lies above the component in the display containment hierarchy. The
* containment need not be direct.
* @param chooser org.netbeans.jemmy.ComponentChooser implementation,
* defining and applying search criteria.
* @return TextComponent instance or null if component was not found.
*/
public static TextComponent findTextComponent(Container cont, ComponentChooser chooser) {
return findTextComponent(cont, chooser, 0);
}
/**
* Searches TextComponent by text.
*
* @param cont Container to search component in.
* @param text TextComponent text. If null, contents is not checked.
* @param ce Compare text exactly.
* @param ccs Compare text case sensitively.
* @param index Ordinal component index.
* @return TextComponent instance or null if component was not found.
* @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
*/
public static TextComponent findTextComponent(Container cont, String text, boolean ce, boolean ccs, int index) {
return findTextComponent(cont, new TextComponentByTextFinder(text, new DefaultStringComparator(ce, ccs)), index);
}
/**
* Searches TextComponent by text.
*
* @param cont Container to search component in.
* @param text TextComponent text. If null, contents is not checked.
* @param ce Compare text exactly.
* @param ccs Compare text case sensitively.
* @return TextComponent instance or null if component was not found.
* @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
*/
public static TextComponent findTextComponent(Container cont, String text, boolean ce, boolean ccs) {
return findTextComponent(cont, text, ce, ccs, 0);
}
/**
* Waits TextComponent in container.
*
* @param cont Container to search component in.
* @param chooser org.netbeans.jemmy.ComponentChooser implementation.
* @param index Ordinal component index.
* @return TextComponent instance.
*/
public static TextComponent waitTextComponent(Container cont, ComponentChooser chooser, int index) {
return (TextComponent) waitComponent(cont, new TextComponentFinder(chooser), index);
}
/**
* Waits 0'th TextComponent in container.
*
* @param cont Container to search component in.
* @param chooser org.netbeans.jemmy.ComponentChooser implementation.
* @return TextComponent instance.
*/
public static TextComponent waitTextComponent(Container cont, ComponentChooser chooser) {
return waitTextComponent(cont, chooser, 0);
}
/**
* Waits TextComponent by text.
*
* @param cont Container to search component in.
* @param text TextComponent text. If null, contents is not checked.
* @param ce Compare text exactly.
* @param ccs Compare text case sensitively.
* @param index Ordinal component index.
* @return TextComponent instance.
* @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
*/
public static TextComponent waitTextComponent(Container cont, String text, boolean ce, boolean ccs, int index) {
return waitTextComponent(cont, new TextComponentByTextFinder(text, new DefaultStringComparator(ce, ccs)), index);
}
/**
* Waits TextComponent by text.
*
* @param cont Container to search component in.
* @param text TextComponent text. If null, contents is not checked.
* @param ce Compare text exactly.
* @param ccs Compare text case sensitively.
* @return TextComponent instance.
* @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
*/
public static TextComponent waitTextComponent(Container cont, String text, boolean ce, boolean ccs) {
return waitTextComponent(cont, text, ce, ccs, 0);
}
static {
Timeouts.initDefault("TextComponentOperator.PushKeyTimeout", PUSH_KEY_TIMEOUT);
Timeouts.initDefault("TextComponentOperator.BetweenKeysTimeout", BETWEEN_KEYS_TIMEOUT);
Timeouts.initDefault("TextComponentOperator.ChangeCaretPositionTimeout", CHANGE_CARET_POSITION_TIMEOUT);
Timeouts.initDefault("TextComponentOperator.TypeTextTimeout", TYPE_TEXT_TIMEOUT);
}
@Override
public void setTimeouts(Timeouts timeouts) {
super.setTimeouts(timeouts);
this.timeouts = timeouts;
}
@Override
public Timeouts getTimeouts() {
return timeouts;
}
@Override
public void setOutput(TestOut out) {
output = out;
super.setOutput(output.createErrorOutput());
}
@Override
public TestOut getOutput() {
return output;
}
@Override
public void copyEnvironment(Operator anotherOperator) {
super.copyEnvironment(anotherOperator);
driver
= (TextDriver) DriverManager.
getDriver(DriverManager.TEXT_DRIVER_ID,
getClass(),
anotherOperator.getProperties());
}
/**
* Changes caret position.
*
* @param position Position to move caret to.
*
*/
public void changeCaretPosition(final int position) {
makeComponentVisible();
produceTimeRestricted(new Action<Void, Void>() {
@Override
public Void launch(Void obj) {
driver.changeCaretPosition(TextComponentOperator.this, position);
return null;
}
@Override
public String getDescription() {
return "Caret moving";
}
@Override
public String toString() {
return "TextComponentOperator.changeCaretPosition.Action{description = " + getDescription() + '}';
}
}, "TextComponentOperator.ChangeCaretPositionTimeout");
}
/**
* Selects a part of text.
*
* @param startPosition Start caret position
* @param finalPosition Final caret position
*
*/
public void selectText(final int startPosition, final int finalPosition) {
makeComponentVisible();
produceTimeRestricted(new Action<Void, Void>() {
@Override
public Void launch(Void obj) {
driver.selectText(TextComponentOperator.this, startPosition, finalPosition);
return null;
}
@Override
public String getDescription() {
return "Text selecting";
}
@Override
public String toString() {
return "TextComponentOperator.selectText.Action{description = " + getDescription() + '}';
}
}, "TextComponentOperator.TypeTextTimeout");
}
/**
* Finds start text position.
*
* @param text Text to be searched.
* @param index Index of text instance (first instance has index 0)
* @return Caret position correspondent to text start.
*/
public int getPositionByText(String text, int index) {
String allText = getText();
int position = 0;
int ind = 0;
while ((position = allText.indexOf(text, position)) >= 0) {
if (ind == index) {
return position;
} else {
ind++;
}
position = position + text.length();
}
return -1;
}
/**
* Finds start text position.
*
* @param text Text to be searched.
* @return Caret position correspondent to text start.
*/
public int getPositionByText(String text) {
return getPositionByText(text, 0);
}
/**
* Clears text.
*
*/
public void clearText() {
output.printLine("Clearing text in text component\n : "
+ toStringSource());
output.printGolden("Clearing text in text component");
makeComponentVisible();
produceTimeRestricted(new Action<Void, Void>() {
@Override
public Void launch(Void obj) {
driver.clearText(TextComponentOperator.this);
return null;
}
@Override
public String getDescription() {
return "Text clearing";
}
@Override
public String toString() {
return "TextComponentOperator.clearText.Action{description = " + getDescription() + '}';
}
}, "TextComponentOperator.TypeTextTimeout");
}
/**
* Types text starting from known position.
*
* @param text Text to be typed.
* @param caretPosition Position to start type text
*/
public void typeText(final String text, final int caretPosition) {
output.printLine("Typing text \"" + text + "\" from "
+ Integer.toString(caretPosition) + " position "
+ "in text component\n : "
+ toStringSource());
output.printGolden("Typing text \"" + text + "\" in text component");
makeComponentVisible();
produceTimeRestricted(new Action<Void, Void>() {
@Override
public Void launch(Void obj) {
driver.typeText(TextComponentOperator.this, text, caretPosition);
return null;
}
@Override
public String getDescription() {
return "Text typing";
}
@Override
public String toString() {
return "TextComponentOperator.typeText.Action{description = " + getDescription() + '}';
}
}, "TextComponentOperator.TypeTextTimeout");
}
/**
* Types text starting from known position.
*
* @param text Text to be typed.
*/
public void typeText(String text) {
typeText(text, getCaretPosition());
}
/**
* Requests a focus, clears text, types new one and pushes Enter.
*
* @param text New text value. Shouldn't include final '\n'.
*
*/
public void enterText(final String text) {
makeComponentVisible();
produceTimeRestricted(new Action<Void, Void>() {
@Override
public Void launch(Void obj) {
driver.enterText(TextComponentOperator.this, text);
return null;
}
@Override
public String getDescription() {
return "Text entering";
}
@Override
public String toString() {
return "TextComponentOperator.enterText.Action{description = " + getDescription() + '}';
}
}, "TextComponentOperator.TypeTextTimeout");
}
@Override
public Hashtable<String, Object> getDump() {
Hashtable<String, Object> result = super.getDump();
result.put(TEXT_DPROP, ((TextComponent) getSource()).getText());
return result;
}
////////////////////////////////////////////////////////
//Mapping //
/**
* Maps {@code TextComponent.addTextListener(TextListener)} through queue
*/
public void addTextListener(final TextListener textListener) {
runMapping(new MapVoidAction("addTextListener") {
@Override
public void map() {
((TextComponent) getSource()).addTextListener(textListener);
}
});
}
/**
* Maps {@code TextComponent.getCaretPosition()} through queue
*/
public int getCaretPosition() {
return (runMapping(new MapIntegerAction("getCaretPosition") {
@Override
public int map() {
return ((TextComponent) getSource()).getCaretPosition();
}
}));
}
/**
* Maps {@code TextComponent.getSelectedText()} through queue
*/
public String getSelectedText() {
return (runMapping(new MapAction<String>("getSelectedText") {
@Override
public String map() {
return ((TextComponent) getSource()).getSelectedText();
}
}));
}
/**
* Maps {@code TextComponent.getSelectionEnd()} through queue
*/
public int getSelectionEnd() {
return (runMapping(new MapIntegerAction("getSelectionEnd") {
@Override
public int map() {
return ((TextComponent) getSource()).getSelectionEnd();
}
}));
}
/**
* Maps {@code TextComponent.getSelectionStart()} through queue
*/
public int getSelectionStart() {
return (runMapping(new MapIntegerAction("getSelectionStart") {
@Override
public int map() {
return ((TextComponent) getSource()).getSelectionStart();
}
}));
}
/**
* Maps {@code TextComponent.getText()} through queue
*/
public String getText() {
return (runMapping(new MapAction<String>("getText") {
@Override
public String map() {
return ((TextComponent) getSource()).getText();
}
}));
}
/**
* Maps {@code TextComponent.isEditable()} through queue
*/
public boolean isEditable() {
return (runMapping(new MapBooleanAction("isEditable") {
@Override
public boolean map() {
return ((TextComponent) getSource()).isEditable();
}
}));
}
/**
* Maps {@code TextComponent.removeTextListener(TextListener)} through queue
*/
public void removeTextListener(final TextListener textListener) {
runMapping(new MapVoidAction("removeTextListener") {
@Override
public void map() {
((TextComponent) getSource()).removeTextListener(textListener);
}
});
}
/**
* Maps {@code TextComponent.select(int, int)} through queue
*/
public void select(final int i, final int i1) {
runMapping(new MapVoidAction("select") {
@Override
public void map() {
((TextComponent) getSource()).select(i, i1);
}
});
}
/**
* Maps {@code TextComponent.selectAll()} through queue
*/
public void selectAll() {
runMapping(new MapVoidAction("selectAll") {
@Override
public void map() {
((TextComponent) getSource()).selectAll();
}
});
}
/**
* Maps {@code TextComponent.setCaretPosition(int)} through queue
*/
public void setCaretPosition(final int i) {
runMapping(new MapVoidAction("setCaretPosition") {
@Override
public void map() {
((TextComponent) getSource()).setCaretPosition(i);
}
});
}
/**
* Maps {@code TextComponent.setEditable(boolean)} through queue
*/
public void setEditable(final boolean b) {
runMapping(new MapVoidAction("setEditable") {
@Override
public void map() {
((TextComponent) getSource()).setEditable(b);
}
});
}
/**
* Maps {@code TextComponent.setSelectionEnd(int)} through queue
*/
public void setSelectionEnd(final int i) {
runMapping(new MapVoidAction("setSelectionEnd") {
@Override
public void map() {
((TextComponent) getSource()).setSelectionEnd(i);
}
});
}
/**
* Maps {@code TextComponent.setSelectionStart(int)} through queue
*/
public void setSelectionStart(final int i) {
runMapping(new MapVoidAction("setSelectionStart") {
@Override
public void map() {
((TextComponent) getSource()).setSelectionStart(i);
}
});
}
/**
* Maps {@code TextComponent.setText(String)} through queue
*/
public void setText(final String string) {
runMapping(new MapVoidAction("setText") {
@Override
public void map() {
((TextComponent) getSource()).setText(string);
}
});
}
//End of mapping //
////////////////////////////////////////////////////////
/**
* Return a TextDriver used by this component.
*
* @return a driver got by the operator during creation.
*/
protected TextDriver getTextDriver() {
return driver;
}
/**
* Allows to find component by text.
*/
public static class TextComponentByTextFinder implements ComponentChooser {
String label;
StringComparator comparator;
/**
* Constructs TextComponentByTextFinder.
*
* @param lb a text pattern
* @param comparator specifies string comparision algorithm.
*/
public TextComponentByTextFinder(String lb, StringComparator comparator) {
label = lb;
this.comparator = comparator;
}
/**
* Constructs TextComponentByTextFinder.
*
* @param lb a text pattern
*/
public TextComponentByTextFinder(String lb) {
this(lb, Operator.getDefaultStringComparator());
}
@Override
public boolean checkComponent(Component comp) {
if (comp instanceof TextComponent) {
if (((TextComponent) comp).getText() != null) {
return (comparator.equals(((TextComponent) comp).getText(),
label));
}
}
return false;
}
@Override
public String getDescription() {
return "TextComponent with text \"" + label + "\"";
}
@Override
public String toString() {
return "TextComponentByTextFinder{" + "label=" + label + ", comparator=" + comparator + '}';
}
}
/**
* Checks component type.
*/
public static class TextComponentFinder extends Finder {
/**
* Constructs TextComponentFinder.
*
* @param sf other searching criteria.
*/
public TextComponentFinder(ComponentChooser sf) {
super(TextComponent.class, sf);
}
/**
* Constructs TextComponentFinder.
*/
public TextComponentFinder() {
super(TextComponent.class);
}
}
}