/* * JBoss, Home of Professional Open Source * Copyright 2013, 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.richfaces.fragment.orderingList; import java.util.List; import org.jboss.arquillian.drone.api.annotation.Drone; import org.jboss.arquillian.graphene.Graphene; import org.jboss.arquillian.graphene.fragment.Root; import org.openqa.selenium.Keys; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Action; import org.richfaces.fragment.common.Actions; import org.richfaces.fragment.common.AdvancedVisibleComponentIteractions; import org.richfaces.fragment.common.Utils; import org.richfaces.fragment.common.VisibleComponentInteractions; import org.richfaces.fragment.common.picker.ChoicePicker; import org.richfaces.fragment.common.picker.ChoicePickerHelper; import org.richfaces.fragment.common.picker.MultipleChoicePicker; import org.richfaces.fragment.list.ListComponent; /** * * @author <a href="mailto:jstefek@redhat.com">Jiri Stefek</a> */ public abstract class AbstractOrderingList implements OrderingList, AdvancedVisibleComponentIteractions<AbstractOrderingList.AdvancedOrderingListInteractions> { @Root private WebElement root; @Drone private WebDriver driver; private final OrderingInteraction orderingInteraction = new OrderingInteractionImpl(); private final PuttingSelectedItem puttingSelectedItem = new PuttingSelectedItemImpl(); @Override public abstract AdvancedOrderingListInteractions advanced(); @Override public PuttingSelectedItem select(String visibleText) { return select(ChoicePickerHelper.byVisibleText().match(visibleText)); } @Override public PuttingSelectedItem select(Integer index) { return select(ChoicePickerHelper.byIndex().index(index)); } @Override public PuttingSelectedItem select(ChoicePicker picker) { unselectAll(); selectItem(picker.pick(advanced().getItemsElements())); return getPuttingSelectedItem(); } protected void selectItem(final WebElement item) { new Actions(driver).keyDown(Keys.CONTROL).click(item).keyUp(Keys.CONTROL).addAction(new Action() { @Override public void perform() { Graphene.waitGui().until().element(item).attribute("class").contains(advanced().getStyleForSelectedItem()); } }).perform(); } protected void selectItems(List<WebElement> list) { for (WebElement webElement : list) { selectItem(webElement); } } protected void unselectAll() { if (!advanced().getSelectedItemsElements().isEmpty()) { new Actions(driver) .click(advanced().getItemsElements().get(0)) .keyDown(Keys.CONTROL).click(advanced().getItemsElements().get(0)) .keyUp(Keys.CONTROL) .addAction(new Action() { @Override public void perform() { Graphene.waitGui().until().element(advanced().getItemsElements().get(0)).attribute("class").not().contains("rf-ord-sel"); } }).perform(); if (!advanced().getSelectedItemsElements().isEmpty()) { throw new RuntimeException("The unselection was not successfull."); } } } protected OrderingInteraction getOrderingInteraction() { return orderingInteraction; } protected PuttingSelectedItem getPuttingSelectedItem() { return puttingSelectedItem; } private class PuttingSelectedItemImpl implements PuttingSelectedItem { private OrderingList putAction(int positionSource, int positionTarget, int differenceToEnd) { if (positionSource != positionTarget) { int differenceBetween = positionTarget - positionSource; int absBetween = Math.abs(differenceBetween); int min = Math.min(absBetween, Math.min(positionTarget, differenceToEnd)); if (min == absBetween) { singleStepMove(differenceBetween); } else if (min == positionTarget) { getOrderingInteraction().top(); if (positionTarget != 0) { singleStepMove(positionTarget); } } else { getOrderingInteraction().bottom(); if (differenceToEnd != 0) { singleStepMove(-differenceToEnd); } } } return AbstractOrderingList.this; } @Override public OrderingList putItAfter(ChoicePicker picker) { int indexOfTargetItem = Utils.getIndexOfElement(picker.pick(advanced().getItemsElements())) + 1; return putAction(Utils.getIndexOfElement(advanced().getSelectedItemsElements().get(0)), indexOfTargetItem, advanced().getItemsElements().size() - indexOfTargetItem); } @Override public OrderingList putItAfter(int index) { return putItAfter(ChoicePickerHelper.byIndex().index(index)); } @Override public OrderingList putItAfter(String match) { return putItAfter(ChoicePickerHelper.byVisibleText().match(match)); } @Override public OrderingList putItBefore(ChoicePicker picker) { int indexOfTargetItem = Utils.getIndexOfElement(picker.pick(advanced().getItemsElements())); return putAction(Utils.getIndexOfElement(advanced().getSelectedItemsElements().get(0)), indexOfTargetItem, advanced().getItemsElements().size() - indexOfTargetItem); } @Override public OrderingList putItBefore(int index) { return putItBefore(ChoicePickerHelper.byIndex().index(index)); } @Override public OrderingList putItBefore(String match) { return putItBefore(ChoicePickerHelper.byVisibleText().match(match)); } private void singleStepMove(int difference) { if (difference == 0) {// no operation } else if (difference > 0) { getOrderingInteraction().down(Math.abs(difference)); } else { getOrderingInteraction().up(Math.abs(difference)); } } } private class OrderingInteractionImpl implements OrderingInteraction { private void checkIfActionPosibleAndPerform(WebElement button, int times) { if (!button.isEnabled()) {// button is enabled only when some items are selected. throw new RuntimeException("No items are selected or button is disabled."); } for (int i = 0; i < times; i++) { button.click(); } } @Override public void bottom() { checkIfActionPosibleAndPerform(advanced().getBottomButtonElement(), 1); } @Override public void down(int times) { checkIfActionPosibleAndPerform(advanced().getDownButtonElement(), times); } @Override public void top() { checkIfActionPosibleAndPerform(advanced().getTopButtonElement(), 1); } @Override public void up(int times) { checkIfActionPosibleAndPerform(advanced().getUpButtonElement(), times); } } public abstract class AdvancedOrderingListInteractions implements VisibleComponentInteractions { public abstract WebElement getBottomButtonElement(); public abstract WebElement getCaptionElement(); public abstract WebElement getDownButtonElement(); public abstract WebElement getHeaderElement(); public abstract List<WebElement> getItemsElements(); public abstract ListComponent<? extends SelectableListItem> getList(); public abstract WebElement getContentAreaElement(); public WebElement getRootElement() { return root; } public abstract List<WebElement> getSelectedItemsElements(); protected abstract String getStyleForSelectedItem(); public abstract WebElement getTopButtonElement(); public abstract WebElement getUpButtonElement(); @Override public boolean isVisible() { return Utils.isVisible(getRootElement()); } public OrderingInteraction select(String visibleText, String... otherTexts) { ChoicePickerHelper.ByVisibleTextChoicePicker picker = ChoicePickerHelper.byVisibleText().allRulesMustPass(false).match(visibleText); for (String string : otherTexts) { picker.match(string); } return select(picker); } public OrderingInteraction select(Integer index, Integer... otherIndexes) { ChoicePickerHelper.ByIndexChoicePicker picker = ChoicePickerHelper.byIndex().index(index); for (Integer integer : otherIndexes) { picker.index(integer); } return select(picker); } public OrderingInteraction select(MultipleChoicePicker picker) { unselectAll(); selectItems(picker.pickMultiple(advanced().getItemsElements())); return getOrderingInteraction(); } } }