blob: 295b9645e836943afa294bdd8f836ec0620675d2 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012 BSI Business Systems Integration AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* BSI Business Systems Integration AG - initial API and implementation
*******************************************************************************/
package org.eclipse.scout.rt.testing.ui.rap;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.rap.rwt.widgets.WidgetUtil;
import org.eclipse.scout.commons.StringUtility;
import org.eclipse.scout.commons.beans.IPropertyObserver;
import org.eclipse.scout.commons.logger.IScoutLogger;
import org.eclipse.scout.commons.logger.ScoutLogManager;
import org.eclipse.scout.rt.client.ClientSyncJob;
import org.eclipse.scout.rt.client.ui.basic.table.ITableRow;
import org.eclipse.scout.rt.testing.shared.TestingUtility;
import org.eclipse.scout.rt.testing.shared.WaitCondition;
import org.eclipse.scout.rt.ui.rap.IRwtEnvironment;
import org.eclipse.scout.rt.ui.rap.basic.ColorUtility;
import org.eclipse.scout.rt.ui.rap.basic.IRwtScoutComposite;
import org.eclipse.scout.rt.ui.rap.basic.RwtScoutComposite;
import org.eclipse.scout.rt.ui.rap.ext.DropDownButton;
import org.eclipse.scout.rt.ui.rap.ext.custom.StyledText;
import org.eclipse.scout.rt.ui.rap.util.RwtUtility;
import org.eclipse.scout.testing.client.AbstractGuiMock;
import org.eclipse.scout.testing.client.IGuiMock;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Scrollable;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.internal.seleniumemulation.ElementFinder;
import org.openqa.selenium.internal.seleniumemulation.JavascriptLibrary;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.service.DriverService;
/**
*
*/
public class RapMock extends AbstractGuiMock {
private static final IScoutLogger LOG = ScoutLogManager.getLogger(RapMock.class);
private static DriverService m_service = null;
private WebDriver m_driver;
private RAPSelenium m_bot;
private int m_sleepDelay = 40;
private final ElementFinder m_elementFinder = new ElementFinder(new JavascriptLibrary());
private String m_currentWidgetId = "";
private WebElement m_currentElement = null;
private boolean m_modifierPressed = false;
private Actions m_actionBuilder = null;
private static boolean useChrome = false;
private static boolean useFirefox = !useChrome;
private static boolean useFirebug = false;// && useFirefox;
public RapMock() {
super(null);
}
@Override
public void initializeMock() {
if (useChrome) {
m_service = new ChromeDriverService.Builder()
.usingDriverExecutable(new File("e:/Downloads/java/chromedriver.exe"))
.usingAnyFreePort()
.build();
}
try {
if (m_service != null) {
m_service.start();
}
}
catch (IOException e) {
throw new IllegalStateException("ChromeDriverService could not be started.", e);
}
}
@Override
public void shutdownMock() {
if (m_service != null) {
m_service.stop();
}
}
@Override
public void beforeTest() {
if (m_service != null) {
if (useChrome) {
DesiredCapabilities chrome = DesiredCapabilities.chrome();
m_driver = new RemoteWebDriver(m_service.getUrl(), chrome);
}
}
else {
if (useFirefox) {
System.setProperty("webdriver.firefox.bin", "C:/FirefoxPortableTest_11/App/Firefox/firefox.exe");
FirefoxProfile firefoxProfile = new FirefoxProfile();
if (useFirebug) {
try {
firefoxProfile.addExtension(new File("E:/Downloads/java/firebug-1.9.2-fx.xpi"));
firefoxProfile.setPreference("extensions.firebug.currentVersion", "1.9.2"); // Avoid startup screen
firefoxProfile.addExtension(new File("E:/Downloads/java/firepath-0.9.7-fx.xpi"));
}
catch (IOException e) {
throw new IllegalStateException("Could not add/find firefox extensions.", e);
}
}
m_driver = new FirefoxDriver(firefoxProfile);
}
}
if (m_driver == null) {
throw new NullPointerException("no driver instantiated!");
}
m_bot = new RAPSelenium(m_driver, "http://localhost:8081");
m_actionBuilder = new Actions(m_bot.getWrappedDriver());
m_bot.open("http://localhost:8081/rap");
m_bot.waitForElementPresent("w2");
}
@Override
public void afterTest() {
m_driver.quit();
}
@Override
public GuiStrategy getStrategy() {
return GuiStrategy.Rap;
}
public void setCurrentWidgetId(String currentWidgetId) {
m_currentWidgetId = currentWidgetId;
m_currentElement = m_elementFinder.findElement(m_bot.getWrappedDriver(), currentWidgetId);
}
public String getCurrentWidgetId_() {
return m_currentWidgetId;
}
public WebElement getCurrentElement() {
return m_currentElement;
}
@Override
public void waitForIdle() {
if (getDisplay().getThread() == Thread.currentThread()) {
return;
}
//
for (int pass = 0; pass < 1; pass++) {
//wait until gui queue is empty
syncExec(new WaitCondition<Object>() {
@Override
public Object run() throws Throwable {
return null;
}
});
//wait until model queue is empty
ClientSyncJob idleJob = new ClientSyncJob("Check for idle", getClientSession()) {
@Override
protected void runVoid(IProgressMonitor m) throws Throwable {
}
};
idleJob.setSystem(true);
final CountDownLatch idleJobScheduledSignal = new CountDownLatch(1);
JobChangeAdapter listener = new JobChangeAdapter() {
@Override
public void done(IJobChangeEvent event) {
idleJobScheduledSignal.countDown();
}
};
try {
idleJob.addJobChangeListener(listener);
idleJob.schedule();
try {
idleJobScheduledSignal.await();
}
catch (InterruptedException e) {
throw new IllegalStateException("Interrupted");
}
}
finally {
idleJob.removeJobChangeListener(listener);
}
}
}
@Override
public void waitForActiveWindow(final String title) {
waitUntil(new WaitCondition<Object>() {
@Override
public Object run() {
if (isWindowActive(title)) {
return true;
}
else {
return null;
}
}
});
waitForIdle();
}
@Override
public void waitForOpenWindow(final String title) {
waitUntil(new WaitCondition<Object>() {
@Override
public Object run() {
if (isWindowOpen(title)) {
return true;
}
else {
return null;
}
}
});
waitForIdle();
}
@Override
public int getSleepDelay() {
return m_sleepDelay;
}
@Override
public void setSleepDelay(int sleepDelay) {
m_sleepDelay = sleepDelay;
}
@Override
public void sleep() {
sleep(getSleepDelay());
}
@Override
public void sleep(int millis) {
//only sleep when NOT in gui thread
if (getDisplay().getThread() == Thread.currentThread()) {
return;
}
//
try {
Thread.sleep(millis);
}
catch (InterruptedException e) {
//nop
}
waitForIdle();
}
@Override
public boolean isWindowActive(final String title) {
return syncExec(new WaitCondition<Boolean>() {
@Override
public Boolean run() throws Throwable {
CTabItem view = findWorkbenchView(title);
if (view != null && view.getParent().getSelection() == view) {
return true;
}
Shell shell = findShell(title);
if (shell != null && shell == getActiveShell()) {
return true;
}
return false;
}
});
}
@Override
public boolean isWindowOpen(final String title) {
return syncExec(new WaitCondition<Boolean>() {
@Override
public Boolean run() throws Throwable {
CTabItem view = findWorkbenchView(title);
if (view != null) {
return true;
}
Shell shell = findShell(title);
if (shell != null) {
return true;
}
return false;
}
});
}
@Override
public void activateWindow(final String title) {
waitForOpenWindow(title);
syncExec(new WaitCondition<Object>() {
@Override
public Object run() throws Throwable {
CTabItem view = findWorkbenchView(title);
if (view != null) {
view.getParent().setSelection(view);
return null;
}
Shell shell = findShell(title);
if (shell != null) {
shell.setActive();
return null;
}
throw new IllegalStateException("There is no view with title " + title);
}
});
waitForIdle();
}
@Override
public FieldState getFieldState(FieldType type, int index) {
final Control c = waitForIndexedField(type, index);
return syncExec(new WaitCondition<FieldState>() {
@Override
public FieldState run() throws Throwable {
return getFieldStateInternal(c);
}
});
}
@Override
public FieldState getScoutFieldState(String name) {
final Control c = waitForScoutField(name);
return syncExec(new WaitCondition<FieldState>() {
@Override
public FieldState run() throws Throwable {
return getFieldStateInternal(c);
}
});
}
@Override
public FieldState getScoutFieldContainerState(String name) {
final Control c = waitForScoutField(name);
return syncExec(new WaitCondition<FieldState>() {
@Override
public FieldState run() throws Throwable {
IRwtScoutComposite swtScoutComposite = RwtScoutComposite.getCompositeOnWidget(c);
if (swtScoutComposite == null) {
return null;
}
return getFieldStateInternal(swtScoutComposite.getUiContainer());
}
});
}
@Override
public List<FieldState> getFieldStates(final FieldType type) {
return syncExec(new WaitCondition<List<FieldState>>() {
@Override
public List<FieldState> run() throws Throwable {
List<FieldState> list = new ArrayList<FieldState>();
for (Control c : RwtUtility.findChildComponents(getActiveShell(), Control.class)) {
if (type == null && getFieldTypeOf(c) != null) {
list.add(getFieldStateInternal(c));
}
else if (type != null && getFieldTypeOf(c) == type) {
list.add(getFieldStateInternal(c));
}
}
return list;
}
});
}
@Override
public FieldState getFocusFieldState() {
return syncExec(new WaitCondition<FieldState>() {
@Override
public FieldState run() throws Throwable {
Control c = getDisplay().getFocusControl();
if (c == null) {
throw new IllegalStateException("There is no focus owner");
}
return getFieldStateInternal(c);
}
});
}
@Override
public void clickOnPushButton(String text) {
final Control c = waitForPushButtonWithLabel(text);
syncExec(new WaitCondition<Object>() {
@Override
public Object run() throws Throwable {
Point p = c.toDisplay(5, 5);
gotoPoint(p.x, p.y);
clickLeft();
return null;
}
});
waitForIdle();
}
@Override
public void gotoField(FieldType type, int index) {
Control c = waitForIndexedField(type, index);
setCurrentWidgetId(WidgetUtil.getId(c));
if (FieldType.Text.equals(type)) {
setCurrentWidgetId(new StringBuffer("//*[@id=\"").append(getCurrentWidgetId_()).append("\"]/input").toString());
}
}
@Override
public void gotoScoutField(String name) {
gotoScoutField(name, 0.5, 0.5);
}
@Override
public void gotoScoutField(String name, double x, double y) {
if (x < 0 || x > 1) {
throw new IllegalArgumentException("x should be in [0, 1] range.");
}
if (y < 0 || y > 1) {
throw new IllegalArgumentException("y should be in [0, 1] range.");
}
final Control c = waitForScoutField(name);
setCurrentWidgetId(WidgetUtil.getId(c));
if (c instanceof Text) {
setCurrentWidgetId(new StringBuffer("//*[@id=\"").append(getCurrentWidgetId_()).append("\"]/input").toString());
}
}
@Override
public void gotoTable(int tableIndex, final int rowIndex, final int columnIndex) {
final Table table = (Table) waitForIndexedField(FieldType.Table, tableIndex);
syncExec(new WaitCondition<Object>() {
@Override
public Object run() throws Throwable {
setCurrentWidgetId(WidgetUtil.getId(table));
StringBuffer xpathWidgetId = new StringBuffer("//*[@id=\"").append(getCurrentWidgetId_()).append("\"]/div[1]/div[").append(rowIndex + table.getColumnCount()).append("]/div");
if (columnIndex > 0) {
xpathWidgetId.append("[").append(columnIndex).append("]");
}
setCurrentWidgetId(xpathWidgetId.toString());
return null;
}
});
}
@Override
public void gotoTableHeader(int tableIndex, final int columnIndex) {
final Table table = (Table) waitForIndexedField(FieldType.Table, tableIndex);
syncExec(new WaitCondition<Object>() {
@SuppressWarnings("null")
@Override
public Object run() throws Throwable {
int curIndex = -1;
int accumulatedWidth = 0;
Rectangle cellBounds = null;
for (int i : table.getColumnOrder()) {
TableColumn col = table.getColumn(i);
//first column is dummy column
if (i > 0) {
curIndex++;
if (curIndex == columnIndex) {
cellBounds = new Rectangle(accumulatedWidth, 0, col.getWidth(), table.getHeaderHeight());
break;
}
}
accumulatedWidth += col.getWidth();
}
cellBounds.x -= table.getHorizontalBar().getSelection();
Point p = table.toDisplay(cellBounds.x + (cellBounds.width / 2), cellBounds.y + (cellBounds.height / 2));
gotoPoint(p.x, p.y);
return null;
}
});
}
@Override
public void gotoTree(int treeIndex, final String nodeText) {
final Tree tree = (Tree) waitForIndexedField(FieldType.Tree, treeIndex);
syncExec(new WaitCondition<Object>() {
@Override
public Object run() throws Throwable {
setCurrentWidgetId(WidgetUtil.getId(tree));
TreeItem[] items = tree.getItems();
for (int i = 0; i < items.length; i++) {
if (nodeText.equals(items[i].getText())) {
StringBuffer xpathWidgetId = new StringBuffer("//*[@id=\"").append(getCurrentWidgetId_()).append("\"]/div[1]/div[").append(i + 1).append("]/div[2]");
setCurrentWidgetId(xpathWidgetId.toString());
break;
}
}
return null;
}
});
}
@Override
public org.eclipse.scout.testing.client.menu.MenuItem getContextMenuItem(String label) {
final MenuItem uiMenuItem = getMenuItem(label);
return syncExec(new WaitCondition<org.eclipse.scout.testing.client.menu.MenuItem>() {
@Override
public org.eclipse.scout.testing.client.menu.MenuItem run() throws Throwable {
if (uiMenuItem != null) {
return new org.eclipse.scout.testing.client.menu.MenuItem(uiMenuItem.getText(), uiMenuItem.isEnabled(), true);
}
else {
return null;
}
}
});
}
@Override
public void contextMenu(final String... names) {
//move to menu
for (int i = 0; i < names.length; i++) {
String label = names[i];
final boolean lastItem = i == names.length - 1;
final MenuItem m = waitForMenuItem(label);
syncExec(new WaitCondition<Boolean>() {
@Override
public Boolean run() throws Throwable {
//toggle
if ((m.getStyle() & (SWT.CHECK | SWT.RADIO)) != 0) {
m.setSelection(!m.getSelection());
}
//fire selection
Event event = new Event();
event.display = getDisplay();
event.time = (int) System.currentTimeMillis();
event.type = SWT.Selection;
event.widget = m;
m.notifyListeners(event.type, event);
if (lastItem) {
//nop
}
return null;
}
});
waitForIdle();
}
}
@Override
public List<String> getTableCells(int tableIndex, final int columnIndex) {
final Table table = (Table) waitForIndexedField(FieldType.Table, tableIndex);
return syncExec(new WaitCondition<List<String>>() {
@Override
public List<String> run() throws Throwable {
ArrayList<String> list = new ArrayList<String>();
for (TableItem row : table.getItems()) {
//first column is dummy column
list.add(row.getText(columnIndex + 1));
}
return list;
}
});
}
@Override
public List<String> getTreeNodes(final int treeIndex) {
final Tree tree = (Tree) waitForIndexedField(FieldType.Tree, treeIndex);
return syncExec(new WaitCondition<List<String>>() {
@Override
public List<String> run() throws Throwable {
ArrayList<String> list = new ArrayList<String>();
addTreeItemsRec(tree.getItems(), list);
return list;
}
});
}
@Override
public Set<String> getSelectedTableCells(int tableIndex, final int columnIndex) {
final Table table = (Table) waitForIndexedField(FieldType.Table, tableIndex);
return syncExec(new WaitCondition<Set<String>>() {
@Override
public Set<String> run() throws Throwable {
TreeSet<String> set = new TreeSet<String>();
TableItem[] sel = table.getSelection();
if (sel != null) {
for (TableItem row : sel) {
//first column is dummy column
set.add(row.getText(columnIndex + 1));
}
}
return set;
}
});
}
@Override
public Set<String> getSelectedTreeNodes(int treeIndex) {
final Tree tree = (Tree) waitForIndexedField(FieldType.Tree, treeIndex);
return syncExec(new WaitCondition<Set<String>>() {
@Override
public Set<String> run() throws Throwable {
TreeSet<String> set = new TreeSet<String>();
TreeItem[] sel = tree.getSelection();
if (sel != null) {
for (TreeItem row : sel) {
set.add(row.getText(0));
}
}
return set;
}
});
}
@Override
public Set<String> getCheckedTableCells(int tableIndex, final int columnIndex) {
final Table table = (Table) waitForIndexedField(FieldType.Table, tableIndex);
return syncExec(new WaitCondition<Set<String>>() {
@Override
public Set<String> run() throws Throwable {
TreeSet<String> check = new TreeSet<String>();
for (int i = 0; i < table.getItemCount(); i++) {
TableItem item = table.getItem(i);
if (item.getData() instanceof ITableRow) {
ITableRow row = (ITableRow) item.getData();
if (row.isChecked()) {
check.add(item.getText(columnIndex + 1));
}
}
}
return check;
}
});
}
@Override
public void gotoPoint(int x, int y) {
final Control c = waitForLocatedField(x, y);
setCurrentWidgetId(WidgetUtil.getId(c));
}
@Override
public void move(int deltaX, int deltaY) {
//XXX RAP
throw new UnsupportedOperationException("not implemented");
}
@Override
public void clickLeft() {
m_bot.clickAndWait(getCurrentWidgetId_());
syncExec(new WaitCondition<Object>() {
@Override
public Object run() throws Throwable {
Control focusControl = Display.getCurrent().getFocusControl();
setCurrentWidgetId(WidgetUtil.getId(focusControl));
return null;
}
});
}
@Override
public void clickRight() {
m_actionBuilder.contextClick(getCurrentElement());
m_actionBuilder.perform();
waitForIdle();
}
@Override
public void drag(int x1, int y1, int x2, int y2) {
//XXX RAP
throw new UnsupportedOperationException("not implemented");
}
@Override
public void dragWindowRightBorder(WindowState windowState, int pixelToMoveOnX) {
int borderSize = 4;
int xPos = windowState.x + windowState.width + borderSize;
int yPos = windowState.y + windowState.height / 2;
drag(xPos, yPos, xPos + pixelToMoveOnX, yPos);
}
@Override
public void typeText(final String text) {
if (m_modifierPressed) {
m_actionBuilder.sendKeys(text.toUpperCase());
}
else {
m_actionBuilder.sendKeys(text).perform();
waitForIdle();
}
}
@Override
public void paste(String text) {
//XXX RAP
throw new UnsupportedOperationException("not implemented");
}
@Override
public void pressKey(Key key) {
switch (key) {
case Shift:
m_actionBuilder.keyDown(Keys.SHIFT);
m_modifierPressed = true;
break;
case Control:
m_actionBuilder.keyDown(Keys.CONTROL);
m_modifierPressed = true;
break;
case Alt:
m_actionBuilder.keyDown(Keys.ALT);
m_modifierPressed = true;
break;
case Windows:
m_actionBuilder.keyDown(Keys.META);
m_modifierPressed = true;
break;
default:
m_actionBuilder.sendKeys(toSeleniumKey(key).toString());
m_actionBuilder.perform();
waitForIdle();
break;
}
}
@Override
public void releaseKey(Key key) {
switch (key) {
case Shift:
m_actionBuilder.keyUp(Keys.SHIFT);
m_modifierPressed = false;
break;
case Control:
m_actionBuilder.keyUp(Keys.CONTROL);
m_modifierPressed = false;
break;
case Alt:
m_actionBuilder.keyUp(Keys.ALT);
m_modifierPressed = false;
break;
case Windows:
m_actionBuilder.keyUp(Keys.META);
m_modifierPressed = false;
break;
default:
m_actionBuilder.keyUp(toSeleniumKey(key));
break;
}
m_actionBuilder.perform();
waitForIdle();
}
@Override
public void typeKey(Key key) {
if (m_modifierPressed) {
m_actionBuilder.sendKeys(toSeleniumKey(key)).perform();
}
else {
m_actionBuilder.sendKeys(getCurrentElement(), toSeleniumKey(key)).perform();
}
waitForIdle();
}
@Override
public WindowState getWindowState(final String title) {
return syncExec(new WaitCondition<WindowState>() {
@Override
public WindowState run() throws Throwable {
checkActiveShell();
CTabItem view = findWorkbenchView(title);
if (view != null) {
WindowState state = new WindowState();
Point p = view.getParent().toDisplay(0, 0);
Point s = view.getParent().getSize();
state.x = p.x;
state.y = p.y;
state.width = s.x;
state.height = s.y;
return state;
}
Shell shell = findShell(title);
if (shell != null) {
Rectangle r = shell.getBounds();
WindowState state = new WindowState();
state.x = r.x;
state.y = r.y;
state.width = r.width;
state.height = r.height;
return state;
}
throw new IllegalStateException("Window " + title + " not found");
}
});
}
@Override
public String getClipboardText() {
waitForIdle();
return syncExec(new WaitCondition<String>() {
@Override
public String run() throws Throwable {
//XXX RAP
return "";
}
});
}
@Override
public void setClipboardText(String value) {
waitForIdle();
syncExec(new WaitCondition<Object>() {
@Override
public String run() throws Throwable {
//XXX RAP
return null;
}
});
}
@Override
public Object internal0(final Object o) {
return syncExec(new WaitCondition<String>() {
@Override
public String run() throws Throwable {
return null;
}
});
}
protected void checkActiveShell() {
if (getActiveShell() == null) {
throw new IllegalStateException("There is no active shell");
}
}
protected FieldState getFieldStateInternal(Control c) {
FieldState state = new FieldState();
//type
state.type = getFieldTypeOf(c);
//scout name
IPropertyObserver scoutObject = RwtScoutComposite.getScoutModelOnWidget(c);
state.scoutName = (scoutObject != null ? scoutObject.getClass().getName() : null);
//focus
state.focus = (c == getDisplay().getFocusControl());
//bounds
Point p = c.toDisplay(0, 0);
state.x = p.x;
state.y = p.y;
state.width = c.getBounds().width;
state.height = c.getBounds().height;
state.foregroundColor = ColorUtility.createStringFromColor(c.getForeground());
state.backgroundColor = ColorUtility.createStringFromColor(c.getBackground());
//text
if (c instanceof Label) {
state.text = ((Label) c).getText();
}
if (c instanceof Text) {
state.text = ((Text) c).getText();
}
if (c instanceof StyledText) {
state.text = ((StyledText) c).getText();
}
if (c instanceof Button) {
Button button = (Button) c;
state.text = button.getText();
// selection
state.selected = button.getSelection();
}
// visibility
state.visible = c.isVisible();
state.widget = c;
return state;
}
protected FieldType getFieldTypeOf(Control c) {
if (c.isDisposed()) {
return null;
}
if (!c.isVisible()) {
return null;
}
//
if (c instanceof Label) {
return FieldType.Label;
}
if (c instanceof Text) {
return FieldType.Text;
}
if (c instanceof StyledText) {
return FieldType.Text;
}
if (c instanceof Table) {
return FieldType.Table;
}
if (c instanceof Tree) {
return FieldType.Tree;
}
if (c instanceof DropDownButton) {
return FieldType.DropdownButton;
}
if (c instanceof Button) {
int style = c.getStyle();
if ((style & SWT.CHECK) != 0) {
return FieldType.Checkbox;
}
else if ((style & SWT.RADIO) != 0) {
return FieldType.RadioButton;
}
else if (c.getParent() instanceof Scrollable) {
return FieldType.ScrollButton;
}
else {
return FieldType.PushButton;
}
}
return null;
}
protected String getScoutNameOf(Control c) {
IPropertyObserver scoutObject = RwtScoutComposite.getScoutModelOnWidget(c);
if (scoutObject != null) {
return scoutObject.getClass().getName();
}
return null;
}
protected Display getDisplay() {
IRwtEnvironment env = (IRwtEnvironment) getClientSession().getData(IRwtEnvironment.ENVIRONMENT_KEY);
return env.getDisplay();
}
protected Shell getActiveShell() {
return getDisplay().getActiveShell();
}
protected String cleanButtonLabel(String s) {
return StringUtility.removeMnemonic(s);
}
protected TreeItem findTreeItemRec(TreeItem[] items, String nodeText) {
if (items == null) {
return null;
}
//
for (TreeItem item : items) {
if (nodeText.equals(item.getText())) {
return item;
}
TreeItem found = findTreeItemRec(item.getItems(), nodeText);
if (found != null) {
return found;
}
}
return null;
}
protected void addTreeItemsRec(TreeItem[] items, List<String> list) {
if (items == null) {
return;
}
//
for (TreeItem item : items) {
list.add(item.getText(0));
addTreeItemsRec(item.getItems(), list);
}
}
protected List<Composite> enumerateParentContainers() {
return syncExec(new WaitCondition<ArrayList<Composite>>() {
@Override
public ArrayList<Composite> run() throws Throwable {
ArrayList<Composite> list = new ArrayList<Composite>();
for (Shell shell : getDisplay().getShells()) {
if (shell.isVisible()) {
list.add(shell);
}
}
return list;
}
});
}
protected Shell findShell(final String title) {
for (Shell shell : getDisplay().getShells()) {
if (title.equals(shell.getText())) {
return shell;
}
}
return null;
}
protected CTabItem findWorkbenchView(final String title) {
return null;
}
protected Control waitForPushButtonWithLabel(final String label) {
return waitUntil(new WaitCondition<Control>() {
@Override
public Control run() {
return syncExec(new WaitCondition<Control>() {
@Override
public Control run() throws Throwable {
for (Shell shell : getDisplay().getShells()) {
Composite parent = shell;
for (Control o : RwtUtility.findChildComponents(parent, Control.class)) {
if (o instanceof Button) {
if (cleanButtonLabel(label).equals(cleanButtonLabel(((Button) o).getText()))) {
return o;
}
}
}
}
return null;
}
});
}
});
}
protected Control waitForScoutField(final String name) {
return waitUntil(new WaitCondition<Control>() {
@Override
public Control run() {
return syncExec(new WaitCondition<Control>() {
@Override
public Control run() throws Throwable {
Control lastSecondaryCandidate = null;
for (Composite parent : enumerateParentContainers()) {
for (Control c : RwtUtility.findChildComponents(parent, Control.class)) {
String s = getScoutNameOf(c);
if (s != null && ("." + s).endsWith("." + name)) {
lastSecondaryCandidate = c;
if (getFieldTypeOf(c) != null) {
//primary match
return c;
}
}
}
}
return lastSecondaryCandidate;
}
});
}
});
}
protected Control waitForIndexedField(final FieldType type, final int fieldIndex) {
return waitUntil(new WaitCondition<Control>() {
@Override
public Control run() {
return syncExec(new WaitCondition<Control>() {
@Override
public Control run() throws Throwable {
List<Composite> parents = enumerateParentContainers();
for (Composite parent : parents) {
int index = 0;
for (Control c : RwtUtility.findChildComponents(parent, Control.class)) {
if (getFieldTypeOf(c) == type) {
if (index == fieldIndex) {
return c;
}
index++;
}
}
}
return null;
}
});
}
});
}
protected Control waitForLocatedField(final int x, final int y) {
return waitUntil(new WaitCondition<Control>() {
@Override
public Control run() {
return syncExec(new WaitCondition<Control>() {
@Override
public Control run() throws Throwable {
List<Composite> parents = enumerateParentContainers();
for (Composite parent : parents) {
for (Control c : RwtUtility.findChildComponents(parent, Control.class, Composite.class)) {
Rectangle map = getDisplay().map(c, null, c.getBounds());
if (map.contains(x, y)) {
return c;
}
}
}
return null;
}
});
}
});
}
protected MenuItem waitForMenuItem(final String name) {
return waitUntil(new WaitCondition<MenuItem>() {
@Override
public MenuItem run() {
return getMenuItem(name);
}
});
}
protected MenuItem getMenuItem(final String name) {
return syncExec(new WaitCondition<MenuItem>() {
@Override
public MenuItem run() throws Throwable {
String label = cleanButtonLabel(name);
//focus control
Control focusControl = getDisplay().getFocusControl();
if (focusControl != null) {
Menu m = focusControl.getMenu();
if (m != null) {
for (MenuItem item : m.getItems()) {
if (label.equals(cleanButtonLabel(item.getText()))) {
return item;
}
}
}
}
//other controls
for (Composite parent : enumerateParentContainers()) {
for (Control c : RwtUtility.findChildComponents(parent, Control.class)) {
Menu m = c.getMenu();
if (m != null) {
for (MenuItem item : m.getItems()) {
if (label.equals(cleanButtonLabel(item.getText()))) {
return item;
}
}
}
}
}
//main menu
for (Shell shell : getDisplay().getShells()) {
Menu m = shell.getMenuBar();
if (m != null) {
for (MenuItem item : m.getItems()) {
if (label.equals(cleanButtonLabel(item.getText()))) {
return item;
}
}
}
}
return null;
}
});
}
protected <T> T syncExec(final WaitCondition<T> r) {
if (getDisplay().getThread() != Thread.currentThread()) {
final AtomicReference<T> ret = new AtomicReference<T>();
final AtomicReference<Throwable> ex = new AtomicReference<Throwable>();
try {
getDisplay().syncExec(new Runnable() {
@Override
public void run() {
try {
ret.set(syncExec(r));
}
catch (Throwable t) {
ex.set(t);
}
}
});
if (ex.get() != null) {
throw ex.get();
}
return ret.get();
}
catch (Throwable t) {
throw new RuntimeException(t);
}
}
//
try {
return r.run();
}
catch (Throwable t) {
throw new RuntimeException(t);
}
}
protected <T> T waitUntil(final WaitCondition<T> w) {
try {
return TestingUtility.waitUntil(WAIT_TIMEOUT, w);
}
catch (Throwable t) {
throw new RuntimeException(t);
}
finally {
waitForIdle();
}
}
@Override
public void pressLeft() {
throw new UnsupportedOperationException("not implemented");
}
@Override
public void releaseLeft() {
throw new UnsupportedOperationException("not implemented");
}
@Override
public void gotoTreeExpandIcon(int treeIndex, String nodeText) {
throw new UnsupportedOperationException("not implemented");
}
protected Keys toSeleniumKey(Key key) {
switch (key) {
case Shift:
return Keys.SHIFT;
case Control:
return Keys.CONTROL;
case Alt:
return Keys.ALT;
case Delete:
return Keys.DELETE;
case Backspace:
return Keys.BACK_SPACE;
case Enter:
return Keys.ENTER;
case Esc:
return Keys.ESCAPE;
case Tab:
return Keys.TAB;
case ContextMenu:
throw new IllegalArgumentException("Unknown keyboard key: " + key);
case Up:
return Keys.UP;
case Down:
return Keys.DOWN;
case Left:
return Keys.LEFT;
case Right:
return Keys.RIGHT;
case Windows:
return Keys.META;
case F1:
return Keys.F1;
case F2:
return Keys.F2;
case F3:
return Keys.F3;
case F4:
return Keys.F4;
case F5:
return Keys.F5;
case F6:
return Keys.F6;
case F7:
return Keys.F7;
case F8:
return Keys.F8;
case F9:
return Keys.F9;
case F10:
return Keys.F10;
case F11:
return Keys.F11;
case F12:
return Keys.F12;
case Home:
return Keys.HOME;
case End:
return Keys.END;
case PageUp:
return Keys.PAGE_UP;
case PageDown:
return Keys.PAGE_DOWN;
case NumPad0:
return Keys.NUMPAD0;
case NumPad1:
return Keys.NUMPAD1;
case NumPad2:
return Keys.NUMPAD2;
case NumPad3:
return Keys.NUMPAD3;
case NumPad4:
return Keys.NUMPAD4;
case NumPad5:
return Keys.NUMPAD5;
case NumPad6:
return Keys.NUMPAD6;
case NumPad7:
return Keys.NUMPAD7;
case NumPad8:
return Keys.NUMPAD8;
case NumPadMultiply:
return Keys.MULTIPLY;
case NumPadDivide:
return Keys.DIVIDE;
case NumPadAdd:
return Keys.ADD;
case NumPadSubtract:
return Keys.SUBTRACT;
case NumPadDecimal:
return Keys.DECIMAL;
case NumPadSeparator:
return Keys.SEPARATOR;
default:
throw new IllegalArgumentException("Unknown keyboard key: " + key);
}
}
protected int toKeyCode(IGuiMock.Key key) {
switch (key) {
case Shift:
return KeyEvent.VK_SHIFT;
case Control:
return KeyEvent.VK_CONTROL;
case Alt:
return KeyEvent.VK_ALT;
case Delete:
return KeyEvent.VK_DELETE;
case Backspace:
return KeyEvent.VK_BACK_SPACE;
case Enter:
return KeyEvent.VK_ENTER;
case Esc:
return KeyEvent.VK_ESCAPE;
case Tab:
return KeyEvent.VK_TAB;
case ContextMenu:
return KeyEvent.VK_CONTEXT_MENU;
case Up:
return KeyEvent.VK_UP;
case Down:
return KeyEvent.VK_DOWN;
case Left:
return KeyEvent.VK_LEFT;
case Right:
return KeyEvent.VK_RIGHT;
case Windows:
return KeyEvent.VK_WINDOWS;
case F1:
return KeyEvent.VK_F1;
case F2:
return KeyEvent.VK_F2;
case F3:
return KeyEvent.VK_F3;
case F4:
return KeyEvent.VK_F4;
case F5:
return KeyEvent.VK_F5;
case F6:
return KeyEvent.VK_F6;
case F7:
return KeyEvent.VK_F7;
case F8:
return KeyEvent.VK_F8;
case F9:
return KeyEvent.VK_F9;
case F10:
return KeyEvent.VK_F10;
case F11:
return KeyEvent.VK_F11;
case F12:
return KeyEvent.VK_F12;
case Home:
return KeyEvent.VK_HOME;
case End:
return KeyEvent.VK_END;
case PageUp:
return KeyEvent.VK_PAGE_UP;
case PageDown:
return KeyEvent.VK_PAGE_DOWN;
case NumPad0:
return KeyEvent.VK_NUMPAD0;
case NumPad1:
return KeyEvent.VK_NUMPAD1;
case NumPad2:
return KeyEvent.VK_NUMPAD2;
case NumPad3:
return KeyEvent.VK_NUMPAD3;
case NumPad4:
return KeyEvent.VK_NUMPAD4;
case NumPad5:
return KeyEvent.VK_NUMPAD5;
case NumPad6:
return KeyEvent.VK_NUMPAD6;
case NumPad7:
return KeyEvent.VK_NUMPAD7;
case NumPad8:
return KeyEvent.VK_NUMPAD8;
case NumPadMultiply:
return KeyEvent.VK_MULTIPLY;
case NumPadDivide:
return KeyEvent.VK_DIVIDE;
case NumPadAdd:
return KeyEvent.VK_ADD;
case NumPadSubtract:
return KeyEvent.VK_SUBTRACT;
case NumPadDecimal:
return KeyEvent.VK_DECIMAL;
case NumPadSeparator:
return KeyEvent.VK_SEPARATOR;
default:
throw new IllegalArgumentException("Unknown keyboard key: " + key);
}
}
@Override
public void clickLeftOnSmartFieldMagnifier(FieldState fieldState) {
throw new UnsupportedOperationException("not implemented yet");
}
@Override
public void clickRightOnSmartFieldMagnifier(FieldState fieldState) {
throw new UnsupportedOperationException("not implemented yet");
}
}