All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.arquillian.ajocado.actions.Drag Maven / Gradle / Ivy

There is a newer version: 2.0.0.Alpha5
Show newest version
/**
 * JBoss, Home of Professional Open Source
 * Copyright 2011, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.arquillian.ajocado.actions;

import static org.jboss.arquillian.ajocado.Graphene.waitGui;

import org.jboss.arquillian.ajocado.framework.GrapheneSelenium;
import org.jboss.arquillian.ajocado.framework.GrapheneSeleniumContext;
import org.jboss.arquillian.ajocado.geometry.Dimension;
import org.jboss.arquillian.ajocado.geometry.Point;
import org.jboss.arquillian.ajocado.locator.element.ElementLocator;
import org.jboss.arquillian.ajocado.waiting.Waiting;

/**
 * 

* Provides item dragging capability to Selenium tests. *

* *

* Methods can be call in following serie: start, mouseOut, move, enter, drop. *

* *

* If we are calling preceding phase (e.g. move, when drag was already called), IllegalStateException is thrown. *

* *

* If we are calling following phase (e.g. drop, when no action was called), all phases preceding requested phase will be done * before requested phase can be done. *

* * @author Lukas Fryc * @version $Revision$ */ public class Drag { /** The Constant NUMBER_OF_STEPS. */ private static final int NUMBER_OF_STEPS = 5; /** The Constant FIRST_STEP. */ private static final int FIRST_STEP = 2; /** * Proxy to local selenium instance */ private GrapheneSelenium selenium = GrapheneSeleniumContext.getProxy(); /** The point. */ private Point currentDelta; // specifies phase in which is dragging state /** The current phase. */ private Phase currentPhase; /** The item to drag. */ private ElementLocator itemToDrag; /** The drag indicator. */ private ElementLocator dragIndicator; /** The drop target. */ private ElementLocator dropTarget; private Point startMove; private Point currentPosition; private Point endPosition; private Point overallMove; private Point reposition = new Point(0, 0); private Point movement = new Point(0, 0); private int numberOfSteps = NUMBER_OF_STEPS; /** The wait. */ private final Waiting wait = waitGui.timeout(10); /** * Initiates Drag object, handled by given Selenium instance, instructing drag of itemToDrag to dropTarget object. * * @param itemToDrag item to drag * @param dropTarget target of item dragging */ public Drag(ElementLocator itemToDrag, ElementLocator dropTarget) { this.currentPhase = Phase.INITIAL; this.itemToDrag = itemToDrag; this.dropTarget = dropTarget; setDropTarget(dropTarget); } public void setDropTarget(ElementLocator dropTarget) { switch (currentPhase) { case INITIAL: startMove = new Point(selenium.getElementWidth(itemToDrag) / 2, selenium.getElementHeight(itemToDrag) / 2); currentPosition = getCenterOfElement(itemToDrag); endPosition = getCenterOfElement(dropTarget); overallMove = endPosition.substract(currentPosition); return; case DROP: throw new IllegalStateException("draggable was already dropped"); case ENTER: selenium.mouseOut(this.dropTarget); break; default: } if (Phase.MOUSE_OUT.before(currentPhase)) { currentPhase = Phase.MOUSE_OUT; } endPosition = getCenterOfElement(dropTarget); overallMove = endPosition.substract(currentPosition); reposition = currentDelta.substract(startMove); movement = new Point(0, 0); this.dropTarget = dropTarget; } public void setDragIndicator(ElementLocator dragIndicator) { this.dragIndicator = dragIndicator; } public void setNumberOfSteps(int numberOfSteps) { this.numberOfSteps = numberOfSteps; } /** * Starts first phase of dragging. * * Simulate left mouse button pressing and small initial movement. */ public void start() { processUntilPhase(Phase.START); } /** * Starts second phase of dragging. * * If there is some unfinished preceding phases, it will be done before this phase. * * Simulate movement of mouse cursor out of the item that ve want to drag. */ public void mouseOut() { processUntilPhase(Phase.MOUSE_OUT); } /** * Starts third phase of dragging. * * If there is some unfinished preceding phases, it will be done before this phase. * * Simulate movement of mouse cursor near the target item. */ public void move() { processUntilPhase(Phase.MOVE); } /** * Starts fourth phase of dragging. * * If there is some unfinished preceding phases, it will be done before this phase. */ public void enter() { processUntilPhase(Phase.ENTER); } /** * Last phase of dragging. * * If there is some unfinished preceding phases, it will be done before this phase. * * Drop the item to target. */ public void drop() { processUntilPhase(Phase.DROP); } /** * Holds whole process of dragging serialized to one switch condition. * * If some phase is called by its number, it will be recognized, that is possible to process this step. * * Internally is used counter 'phase' which will be decreased when passed to a new phase. Switch condition breaks when will * finished in requesting phase. */ private void processUntilPhase(Phase requestedPhase) { if (requestedPhase.before(currentPhase)) { throw new IllegalArgumentException("Requested phase (" + requestedPhase + ") is before current phase (" + currentPhase + ")"); } while ((currentPhase.before(requestedPhase))) { currentPhase = currentPhase.next(); executePhase(currentPhase); } } /** * Executes the instructions for given phase. * * @param phase the phase what should be executed */ private void executePhase(Phase phase) { switch (phase) { case START: currentDelta = startMove.add(new Point((overallMove.getX() < 0) ? FIRST_STEP : -FIRST_STEP, (overallMove.getY() < 0) ? FIRST_STEP : -FIRST_STEP)); selenium.mouseDownAt(itemToDrag, new Point(0, 0)); selenium.mouseMoveAt(itemToDrag, new Point(2, 2)); if (dragIndicator != null && selenium.isElementPresent(dragIndicator)) { startMove = startMove.substract(getCentral(dragIndicator)); } selenium.mouseMoveAt(itemToDrag, startMove); break; case MOUSE_OUT: selenium.mouseOut(itemToDrag); break; case MOVE: for (int i = 0; i < numberOfSteps; i++) { Point oldMovement = movement; movement = new Point(overallMove.getX() * i / numberOfSteps, overallMove.getY() * i / numberOfSteps); Point movementDelta = movement.substract(oldMovement); currentDelta = reposition.add(startMove).add(movement); selenium.mouseMoveAt(itemToDrag, currentDelta); currentPosition = currentPosition.add(movementDelta); wait.waitForTimeout(); } break; case ENTER: currentDelta = reposition.add(startMove).add(overallMove); currentPosition = endPosition; selenium.mouseMoveAt(itemToDrag, currentDelta); selenium.mouseOverAt(dropTarget, currentDelta); break; case DROP: selenium.mouseUp(dropTarget); break; default: } } /** * Enumeration of phases supported by this {@link Drag} object. */ public enum Phase { INITIAL, START, MOUSE_OUT, MOVE, ENTER, DROP; /** * Compares given phase to this phase. * * @param phase the phase * @return true, if given phase is before this phase; else otherwise */ boolean before(Phase phase) { return this.compareTo(phase) < 0; } /** * Return next phase in order after this phase. * * @return the next phase in oder after this phase */ Phase next() { boolean returnNextPhase = false; for (Phase phase : Phase.values()) { if (returnNextPhase) { return phase; } if (this == phase) { returnNextPhase = true; } } return null; } } private Point getCentral(ElementLocator element) { Dimension dimension = selenium.getElementDimension(element); Point central = new Point(dimension.getWidth() / 2, dimension.getHeight() / 2); return central; } private Point getCenterOfElement(ElementLocator element) { return selenium.getElementPosition(element).add(getCentral(element)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy