package utils.swtbot;
import java.util.List;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.bindings.keys.ParseException;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTableItem;
import org.junit.Assert;
/**
* The сlass that encapsulates UI testing Bot with it`s default preferences.
*
* @author <a href="mailto:Daniil.Yaroslavtsev@gmail.com">Daniil Yaroslavtsev</a>
*/
public class UITest extends Assert {
/** The Bot for UI testing. */
private static final SWTWorkbenchBot BOT = new SWTWorkbenchBot();
/**
* The default tests playback delay in ms. Changes an execution speed of SWTBot tests. System default is 0.
* */
private static int defaultPlaybackDelay = 0;
/**
* The default timeout before SWTBot tests execution.
* */
private static int timeBeforeTestsTimeout = 0;
/** The timeout between two tests execution in ms. */
private static int defaultBetweenTestsTimaout = 0;
/**
* Gets the bot.
*
* @return The current UI testing bot.
*/
protected static SWTWorkbenchBot getBot() {
return BOT;
}
protected static int getDefaultTestsPlaybackDelay() {
return defaultPlaybackDelay;
}
/**
* Setups the necessary bot parameters.
*/
protected static void setupSWTBotParams() {
// Set timeout for execution of SWTBot tests. System default is 0.
SWTBotPreferences.TIMEOUT = timeBeforeTestsTimeout;
// Set execution speed of SWTBot tests. System default is 0.
setTestsPlaybackDelay(defaultPlaybackDelay);
}
/**
* Sets the tests playback delay in ms.
*
* @param milliseconds
* - the new tests playback delay.
*/
protected static void setTestsPlaybackDelay(final int milliseconds) {
SWTBotPreferences.PLAYBACK_DELAY = milliseconds;
}
/**
* Causes the bot to sleep during default time between tests
*/
protected static void doSleepBetweenTests() {
BOT.sleep(defaultBetweenTestsTimaout);
}
/**
* Closes all unnecessary editors, shells and all views except "Log4j-Viewer".
*/
protected static void closeUnnecessaryViewsIfNeeded() {
BOT.closeAllEditors();
BOT.closeAllShells();
// close all views except "Log4j-Viewer".
List<SWTBotView> curOpenedViewsList = BOT.views();
for (SWTBotView view : curOpenedViewsList) {
String curViewTitle = view.getTitle();
if (curViewTitle.equals("Log4j-Viewer")) {
// no code
} else {
view.close();
}
}
}
/**
* Gets a KeyStroke for the key defined by the keyCode.
*
* @param keyCode
* - any SWT keyCode.
* @return The new KeyStroke instance for the specified key.
*/
protected KeyStroke getKey(final int keyCode) {
return KeyStroke.getInstance(keyCode);
}
/**
* Writes the text to the specified cell of parent table in loverCase letters by alphanumeric keys pressing.
*
* @param table
* - the parent table.
* @param row
* - the row number.
* @param column
* - the column number.
* @param text
* - the alphanumeric text.
* @param editorActivationType
* - the editor activation type.
* @throws ParseException
* if the current keyCode is not an alphanumeric key code.
*/
protected void writeToCell(final TableViewer viewer, final int row, final int column, final String text,
final int editorActivationType) throws ParseException {
final SWTBotTable table = new SWTBotTable(viewer.getTable());
table.select(row);
SWTBotTableItem item = table.getTableItem(row);
startEditing(viewer, row, column, editorActivationType);
for (char keyChar : text.toLowerCase().toCharArray()) {
if (isAlphanumericKey(keyChar)) {
item.pressShortcut(getKey(keyChar));
} else {
throw new ParseException("Can`t parse key: \"" + keyChar + "\" - it is not an alphanumeric key!");
}
}
}
/**
* Checks that specified number is a code of SWT alphanumeric key (lovercase keys only).
*
* @param keyCode
* - SWT key code.
* @return true, if specified number is a code of alphanumeric key.
*/
private boolean isAlphanumericKey(final int keyCode) {
return ((keyCode >= 48) && (keyCode <= 57)) // 0..9 numbers
|| ((keyCode >= 97) && (keyCode <= 122)); // a - z (loverCase only!)
}
/**
* Starts the cell editor for the cell specified by row and column number.
*
* @param table
* - the parent table.
* @param row
* - the row number.
* @param column
* - the column number.
* @param editorActivationType
* - the editor activation type.
* @throws IllegalArgumentException
* if an invalid editor activation type specified.
* @see MOUSE_CLICK_ACTIVATION
*/
protected void startEditing(final TableViewer viewer, final int row, final int column,
final int editorActivationType) {
final SWTBotTable table = new SWTBotTable(viewer.getTable());
switch (editorActivationType) {
case UITestConstants.MOUSE_CLICK_ACTIVATION:
table.click(row, column);
break;
case UITestConstants.MOUSE_DOUBLE_CLICK_ACTIVATION:
table.doubleClick(row, column);
break;
case UITestConstants.F2_KEY_ACTIVATION:
table.click(row, column);
table.pressShortcut(getKey(SWT.F2));
break;
default:
throw new IllegalArgumentException("Can`t support the specified editor activation type.");
}
waitForCellEditorState(viewer, true);
}
/**
* Generates a Random integer number within a given range.
*
* @param begin
* - the range begin.
* @param end
* - the range end.
* @return random number that is in the given range.
*/
protected int randomInt(final int begin, final int end) {
return (int) (begin + (Math.random() * ((end - begin) + 1)));
}
/**
* Waits until the default timeout is reached or until the TableViewer cell editor`s "isActive()" state becomes
* equal to the specified state (true/false).
*
* @param tableWiewer
* - the TableViewer to retrieve the cell editor state.
* @param condition
* -
*/
protected void waitForCellEditorState(final TableViewer tableWiewer, final boolean condition) {
BOT.waitUntil(new CellEditorWaiter(tableWiewer, condition), UITestConstants.DEFAULT_CELL_EDITOR_TIMEOUT);
}
/**
* Waits for UI repaint.
*/
protected void waitForUIRepaint() {
BOT.sleep(100);
}
/**
* Causes the bot to wait.
*
* @param millis
* - wait time in milliseconds.
* */
protected void sleep(final int millis) {
BOT.sleep(millis);
}
class CellEditorWaiter extends DefaultCondition {
private final TableViewer tableWiewer;
private final boolean condition;
// initialize
CellEditorWaiter(final TableViewer tableWiewer, final boolean condition) {
this.tableWiewer = tableWiewer;
this.condition = condition;
}
// return true if the condition matches, false otherwise
@Override
public boolean test() {
return tableWiewer.isCellEditorActive() == condition;
}
// provide a human readable error message
@Override
public String getFailureMessage() {
return "Timed out while waiting for the cell editor.";
}
}
}