Java tutorial
/******************************************************************************* * 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.lifecycle.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.IClientSession; 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.IRwtScoutComposite; import org.eclipse.scout.rt.ui.rap.basic.RwtScoutComposite; import org.eclipse.scout.rt.ui.rap.ext.IDropDownButtonForPatch; 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.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 implements IGuiMock { private static final IScoutLogger LOG = ScoutLogManager.getLogger(RapMock.class); static interface MockRunnable<T> extends WaitCondition<T> { } private static DriverService m_service = null; private WebDriver m_driver; private RAPSelenium m_bot; private IClientSession m_session; 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 List<CharSequence> m_keyList = new ArrayList<CharSequence>(); private static boolean useChrome = false; private static boolean useFirefox = !useChrome; private static boolean useFirebug = false && useFirefox; public void setClientSession(IClientSession session) { m_session = session; } @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); // m_driver = new FirefoxDriver(new FirefoxProfile(new File("C:/Temp/webdriver-profile"))); } } 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 MockRunnable<Object>() { @Override public Object run() throws Throwable { return null; } }); //wait until model queue is empty ClientSyncJob idleJob = new ClientSyncJob("Check for idle", m_session) { @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 MockRunnable<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 MockRunnable<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 MockRunnable<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 MockRunnable<FieldState>() { @Override public FieldState run() throws Throwable { return getFieldStateInternal(c); } }); } @Override public FieldState getScoutFieldState(String name) { final Control c = waitForScoutField(name); return syncExec(new MockRunnable<FieldState>() { @Override public FieldState run() throws Throwable { return getFieldStateInternal(c); } }); } @Override public FieldState getScoutFieldContainerState(String name) { final Control c = waitForScoutField(name); return syncExec(new MockRunnable<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 MockRunnable<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 MockRunnable<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 MockRunnable<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.getAdapter(c).getId()); if (FieldType.Text.equals(type)) { setCurrentWidgetId( new StringBuffer("//*[@id=\"").append(getCurrentWidgetId_()).append("\"]/input").toString()); } } @Override public void gotoScoutField(String name) { final Control c = waitForScoutField(name); setCurrentWidgetId(WidgetUtil.getAdapter(c).getId()); 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 MockRunnable<Object>() { @Override public Object run() throws Throwable { setCurrentWidgetId(WidgetUtil.getAdapter(table).getId()); 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 MockRunnable<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 MockRunnable<Object>() { @Override public Object run() throws Throwable { setCurrentWidgetId(WidgetUtil.getAdapter(tree).getId()); 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 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 MockRunnable<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 MockRunnable<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 MockRunnable<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 MockRunnable<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 MockRunnable<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 MockRunnable<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.getAdapter(c).getId()); } @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 MockRunnable<Object>() { @Override public Object run() throws Throwable { Control focusControl = Display.getCurrent().getFocusControl(); setCurrentWidgetId(WidgetUtil.getAdapter(focusControl).getId()); 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"); /* gotoPoint(x1, y1); m_bot.pressLeft(); gotoPoint(x2, y2); m_bot.releaseLeft(); waitForIdle(); */ } @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()); // m_bot.typeKeys(getCurrentWidgetId(), text); // m_keyList.add(text); } else { m_actionBuilder.sendKeys(text).perform(); waitForIdle(); } } @Override public void paste(String text) { //XXX RAP throw new UnsupportedOperationException("not implemented"); /* Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(text), null); //press paste (ctrl-V) m_bot.pressKey(Key.Control); m_bot.typeText("v"); m_bot.releaseKey(Key.Control); */ } @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_bot.controlKeyDown(); // m_bot.keyDownNative("17"); // m_keyList.add(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(); // m_bot.keyDown(m_currentWidgetId, toSeleniumKey(key)); 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_bot.controlKeyUp(); // m_bot.keyUpNative("17"); // getCurrentElement().sendKeys(m_keyList.toArray(new CharSequence[m_keyList.size()])); // m_keyList.clear(); // getCurrentElement().sendKeys(Keys.CONTROL, "a"); 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)); // m_bot.keyUp(m_currentWidgetId, 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(); // m_bot.keyPress(toSeleniumKey(key).toString()); } waitForIdle(); } @Override public WindowState getWindowState(final String title) { return syncExec(new MockRunnable<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 MockRunnable<String>() { @Override public String run() throws Throwable { //XXX RAP // Clipboard b = new Clipboard(getDisplay()); // return (String) b.getContents(TextTransfer.getInstance()); return ""; } }); } @Override public Object internal0(final Object o) { return syncExec(new MockRunnable<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; //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) { state.text = ((Button) c).getText(); } 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 IDropDownButtonForPatch) { 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) m_session.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 MockRunnable<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) { //XXX RAP // Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();XXX RAP // if (shell != null) { // for (CTabFolder f : SwtUtility.findChildComponents(shell, CTabFolder.class)) { // if (f.getItemCount() > 0) { // for (CTabItem item : f.getItems()) { // if (item.isShowing()) { // if (title.equals(cleanButtonLabel(item.getText()))) { // return item; // } // } // } // } // } // } return null; } protected Control waitForPushButtonWithLabel(final String label) { return waitUntil(new WaitCondition<Control>() { @Override public Control run() { return syncExec(new MockRunnable<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 MockRunnable<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 MockRunnable<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 MockRunnable<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 syncExec(new MockRunnable<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 MockRunnable<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); } } }