/******************************************************************************* * Copyright (c) 2012 Google, Inc. * 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: * Google, Inc. - initial API and implementation *******************************************************************************/ package com.windowtester.internal.runtime.selector; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import com.windowtester.internal.runtime.locator.IUISelector; import com.windowtester.internal.runtime.system.WidgetSystem; import com.windowtester.runtime.ClickDescription; import com.windowtester.runtime.IAdaptable; import com.windowtester.runtime.IClickDescription; import com.windowtester.runtime.IUIContext; import com.windowtester.runtime.WT; import com.windowtester.runtime.WidgetSearchException; import com.windowtester.runtime.locator.IItemLocator; import com.windowtester.runtime.locator.ILocator; import com.windowtester.runtime.locator.IMenuItemLocator; import com.windowtester.runtime.locator.IWidgetLocator; import com.windowtester.runtime.locator.IWidgetReference; import com.windowtester.runtime.locator.XYLocator; /** * A helper class that parses and performs click commands. */ public class ClickHelper implements IClickDriver { private final IUIContext _ui; //for click listeners private List _listeners; public ClickHelper(IUIContext ui) { _ui = ui; } /* (non-Javadoc) * @see com.windowtester.internal.runtime.selector.IClickDriver#click(int, com.windowtester.runtime2.locator.ILocator, int) */ public IWidgetLocator click(int clickCount, ILocator locator, int buttonMask) throws WidgetSearchException { //extract widget reference IWidgetLocator wl = getWidgetLocator(locator); //might be wrapped in an XYLocator // if (wl == null) // return absoluteClick(..) IWidgetReference widget = null; //should be a null object /* * Don't look for path based widgets... */ if (!(wl instanceof IItemLocator)) widget = doFind(wl); //if no WL is found, it's an absolute click? //create click description IClickDescription click = createClickDescription(clickCount, locator, buttonMask); IUISelector selector = getSelector(wl); IWidgetLocator clicked = doClick(widget, click, selector); informClick(click, clicked); return clicked; } /* (non-Javadoc) * @see com.windowtester.internal.runtime.selector.IClickDriver#contextClick(com.windowtester.runtime2.locator.ILocator, com.windowtester.runtime2.locator.IMenuItemLocator) */ public IWidgetLocator contextClick(ILocator locator, IMenuItemLocator menuItem) throws WidgetSearchException { IWidgetLocator wl = getWidgetLocator(locator); IWidgetReference widget = null; //should be a null object /* * Don't look for path based widgets... */ if (!(wl instanceof IItemLocator)) widget = doFind(wl); //if no WL is found, it's an absolute click? //create click description IClickDescription click = createClickDescription(1 /*clickCount*/, locator, WT.BUTTON3); IUISelector selector = getSelector(wl); IWidgetLocator clicked = doContextClick(menuItem, widget, click, selector); informContextClick(click, clicked); return clicked; } /** * Get the selector associated with this locator. */ private IUISelector getSelector(ILocator locator) { if (locator instanceof IUISelector) return (IUISelector)locator; IUISelector selector = null; if (locator instanceof IAdaptable) selector = (IUISelector)((IAdaptable)locator).getAdapter(IUISelector.class); if (selector != null) return selector; if (locator instanceof IWidgetReference) return WidgetSystem.getDefaultSelector(((IWidgetReference)locator).getWidget()); throw new IllegalStateException(); } /** * Get the WidgetLocator associated with this ILocator. */ public static IWidgetLocator getWidgetLocator(ILocator locator) { if (locator instanceof IWidgetLocator) return (IWidgetLocator)locator; if (locator instanceof XYLocator) { //notice that arbitrary nesting is suported here -- should it be? return getWidgetLocator(((XYLocator)locator).locator()); } //SHOULD THROW EXCEPTION HERE? return null; } private IClickDescription createClickDescription(int clickCount, ILocator locator, int buttonMask) { // TODO properly handle nested XYLocators return ClickDescription.create(clickCount, locator, buttonMask); } private IUIContext getUIContext() { return _ui; } /* (non-Javadoc) * @see com.windowtester.internal.runtime.selector.IClickDriver#addClickListener(com.windowtester.internal.runtime.selector.IClickDriver.Listener) */ public void addClickListener(Listener listener) { getListeners().add(listener); } private void informClick(IClickDescription click, IWidgetLocator clicked) { for (Iterator iter = getListeners().iterator(); iter.hasNext();) { Listener listener = (Listener) iter.next(); listener.clicked(click, clicked); } } private void informContextClick(IClickDescription click, IWidgetLocator clicked) { for (Iterator iter = getListeners().iterator(); iter.hasNext();) { Listener listener = (Listener) iter.next(); listener.contextClicked(click, clicked); } } private List getListeners() { if (_listeners == null) _listeners = new ArrayList(); return _listeners; } /////////////////////////////////////////////////////////////////////////////////////// // // Wrappers that adapt legacy exceptions appropriately. // /////////////////////////////////////////////////////////////////////////////////////// private IWidgetLocator doClick(IWidgetReference widget, IClickDescription click, IUISelector selector) throws WidgetSearchException { // try { return selector.click(getUIContext(), widget, click); // TODO [Dan] Not a single subclass of WidgetSearchException implements IAdaptable, so I commented this out // } catch (WidgetSearchException e) { // if (e instanceof IAdaptable) { // WidgetSearchException adapted = (WidgetSearchException) ((IAdaptable)e).getAdapter(WidgetSearchException.class); // if (adapted != null) // throw adapted; // } // throw e; // } } private IWidgetReference doFind(IWidgetLocator wl) throws WidgetSearchException { // try { return (IWidgetReference) getUIContext().find(wl); // TODO [Dan] Not a single subclass of WidgetSearchException implements IAdaptable, so I commented this out // } catch (WidgetSearchException e) { // if (e instanceof IAdaptable) { // WidgetSearchException adapted = (WidgetSearchException) ((IAdaptable)e).getAdapter(WidgetSearchException.class); // if (adapted != null) // throw adapted; // } // throw e; // } } private IWidgetLocator doContextClick(IMenuItemLocator menuItem, IWidgetReference widget, IClickDescription click, IUISelector selector) throws WidgetSearchException { // try { return selector.contextClick(getUIContext(), widget, click, menuItem.getPath()); // TODO [Dan] Not a single subclass of WidgetSearchException implements IAdaptable, so I commented this out // } catch (WidgetSearchException e) { // if (e instanceof IAdaptable) { // WidgetSearchException adapted = (WidgetSearchException) ((IAdaptable)e).getAdapter(WidgetSearchException.class); // if (adapted != null) // throw adapted; // } // throw e; // } } }