org.richfaces.fragment.panelMenu.AbstractPanelMenu Maven / Gradle / Ivy
/*
* 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.panelMenu;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.graphene.Graphene;
import org.jboss.arquillian.graphene.condition.element.WebElementConditionFactory;
import org.jboss.arquillian.graphene.wait.FluentWait;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.richfaces.fragment.common.AdvancedVisibleComponentIteractions;
import org.richfaces.fragment.common.Event;
import org.richfaces.fragment.common.Utils;
import org.richfaces.fragment.common.VisibleComponentInteractions;
import org.richfaces.fragment.common.WaitingWrapper;
import org.richfaces.fragment.common.WaitingWrapperImpl;
import org.richfaces.fragment.common.picker.ChoicePicker;
import org.richfaces.fragment.common.picker.ChoicePickerHelper;
import com.google.common.base.Predicate;
public abstract class AbstractPanelMenu implements PanelMenu, PanelMenuGroup, AdvancedVisibleComponentIteractions {
@ArquillianResource
private JavascriptExecutor executor;
@Drone
private WebDriver browser;
@Override
public PanelMenuItem selectItem(ChoicePicker picker) {
WebElement itemRoot = picker.pick(getMenuItems());
ensureElementExist(itemRoot);
ensureElementIsEnabledAndVisible(itemRoot);
RichFacesPanelMenuItem panelMenuItem = Graphene.createPageFragment(RichFacesPanelMenuItem.class, itemRoot);
panelMenuItem.select();
return panelMenuItem;
}
@Override
public PanelMenuItem selectItem(String header) {
return selectItem(ChoicePickerHelper.byVisibleText().match(header));
}
@Override
public PanelMenuItem selectItem(int index) {
return selectItem(ChoicePickerHelper.byIndex().index(index));
}
@Override
public PanelMenuGroup expandGroup(ChoicePicker picker) {
WebElement groupRoot = picker.pick(getMenuGroups());
ensureElementExist(groupRoot);
ensureElementIsEnabledAndVisible(groupRoot);
WebElement groupHeader = getHeaderElementDynamically(groupRoot);
if (isGroupExpanded(groupHeader)) {
return Graphene.createPageFragment(RichFacesPanelMenuGroup.class, groupRoot);
}
executeEventOn(advanced().getExpandEvent(), groupHeader);
advanced().waitUntilMenuGroupExpanded(groupHeader).perform();
return Graphene.createPageFragment(RichFacesPanelMenuGroup.class, groupRoot);
}
@Override
public PanelMenuGroup expandGroup(String header) {
return expandGroup(ChoicePickerHelper.byVisibleText().startsWith(header));
}
@Override
public PanelMenuGroup expandGroup(int index) {
return expandGroup(ChoicePickerHelper.byIndex().index(index));
}
@Override
public void collapseGroup(ChoicePicker picker) {
WebElement groupRoot = picker.pick(getMenuGroups());
ensureElementExist(groupRoot);
ensureElementIsEnabledAndVisible(groupRoot);
WebElement groupHeader = getHeaderElementDynamically(groupRoot);
if (!isGroupExpanded(groupHeader)) {
return;
}
executeEventOn(advanced().getCollapseEvent(), groupHeader);
advanced().waitUntilMenuGroupCollapsed(groupHeader).perform();
}
@Override
public void collapseGroup(String header) {
collapseGroup(ChoicePickerHelper.byVisibleText().startsWith(header));
}
@Override
public void collapseGroup(int index) {
collapseGroup(ChoicePickerHelper.byIndex().index(index));
}
@Override
public PanelMenu expandAll() {
throw new UnsupportedOperationException();
}
@Override
public PanelMenu collapseAll() {
throw new UnsupportedOperationException();
}
public abstract List getMenuItems();
public abstract List getMenuGroups();
public abstract AdvancedAbstractPanelMenuInteractions advanced();
public abstract class AdvancedAbstractPanelMenuInteractions implements VisibleComponentInteractions {
private static final String CSS_EXPANDED_SUFFIX = "-exp";
private static final String CSS_TRANSPARENT_SUFFIX = "-transparent";
private static final String CSS_SELECTED_SUFFIX = "-sel";
private static final String CSS_HOVERED_SUFFIX = "-hov";
private static final String CSS_DISABLED_SUFFIX = "-dis";
private static final String CSS_COLLAPSED_SUFFIX = "-colps";
private static final String HEADER_SELECTOR_TO_INVOKE_EVENT_ON = "div[class*=rf-pm-][class*=-gr-hdr]";
private Event expandEvent = Event.CLICK;
private Event collapseEvent = Event.CLICK;
private long _timoutForMenuGroupToBeExpanded = -1;
private long _timeoutForMenuGroupToBeCollapsed = -1;
protected String getHeaderSelectorToInovkeEventOn() {
return HEADER_SELECTOR_TO_INVOKE_EVENT_ON;
}
protected String getCssExpandedSuffix() {
return CSS_EXPANDED_SUFFIX;
}
protected String getCssTransparentSuffix() {
return CSS_TRANSPARENT_SUFFIX;
}
protected String getCssSelectedSuffix() {
return CSS_SELECTED_SUFFIX;
}
protected String getCssHoveredSuffix() {
return CSS_HOVERED_SUFFIX;
}
protected String getCssDisabledSuffix() {
return CSS_DISABLED_SUFFIX;
}
protected String getCssCollapsedSuffix() {
return CSS_COLLAPSED_SUFFIX;
}
protected Event getExpandEvent() {
return expandEvent;
}
protected Event getCollapseEvent() {
return collapseEvent;
}
public void setExpandEvent(Event event) {
expandEvent = event;
}
public void setCollapseEvent(Event event) {
collapseEvent = event;
}
public boolean isGroupExpanded(WebElement groupRoot) {
return AbstractPanelMenu.this.isGroupExpanded(getHeaderElementDynamically(groupRoot));
}
public WaitingWrapper waitUntilMenuGroupExpanded(final WebElement groupHeader) {
return new WaitingWrapperImpl() {
@Override
protected void performWait(FluentWait wait) {
wait.ignoring(org.openqa.selenium.remote.ErrorHandler.UnknownServerException.class).until(
new Predicate() {
@Override
public boolean apply(WebDriver input) {
return AbstractPanelMenu.this.isGroupExpanded(groupHeader);
}
});
}
}.withMessage("Waiting for Panel Menu group to be expanded!")
.withTimeout(getTimoutForMenuGroupToBeExpanded(), TimeUnit.MILLISECONDS);
}
public WaitingWrapper waitUntilMenuGroupCollapsed(final WebElement groupHeader) {
return new WaitingWrapperImpl() {
@Override
protected void performWait(FluentWait wait) {
wait.ignoring(org.openqa.selenium.remote.ErrorHandler.UnknownServerException.class).until(
new Predicate() {
@Override
public boolean apply(WebDriver input) {
return !AbstractPanelMenu.this.isGroupExpanded(groupHeader);
}
});
}
}.withMessage("Waiting for Panel Menu group to be expanded!")
.withTimeout(getTimeoutForMenuGroupToBeCollapsed(), TimeUnit.MILLISECONDS);
}
public void setTimoutForMenuGroupToBeExpanded(long timeoutInMilliseconds) {
_timoutForMenuGroupToBeExpanded = timeoutInMilliseconds;
}
public long getTimoutForMenuGroupToBeExpanded() {
return _timoutForMenuGroupToBeExpanded == -1 ? Utils.getWaitAjaxDefaultTimeout(browser) : _timoutForMenuGroupToBeExpanded;
}
public void setTimeoutForMenuGroupToBeCollapsed(long timeoutInMilliseconds) {
_timeoutForMenuGroupToBeCollapsed = timeoutInMilliseconds;
}
public long getTimeoutForMenuGroupToBeCollapsed() {
return _timeoutForMenuGroupToBeCollapsed == -1 ? Utils.getWaitAjaxDefaultTimeout(browser) : _timeoutForMenuGroupToBeCollapsed;
}
protected abstract WebElement getRootElement();
@Override
public boolean isVisible() {
return Utils.isVisible(getRootElement());
}
}
private boolean isGroupExpanded(WebElement groupHeader) {
return groupHeader.getAttribute("class").contains(advanced().getCssExpandedSuffix());
}
private void ensureElementIsEnabledAndVisible(WebElement element) {
checkElementIsVisible(element);
if (isDisabled(element)) {
throw new IllegalArgumentException("Element " + element + " can not be interacted with, as it is disabled.");
}
}
private boolean isDisabled(WebElement group) {
return group.getAttribute("class").contains(advanced().getCssDisabledSuffix());
}
private void checkElementIsVisible(WebElement element) {
if (!new WebElementConditionFactory(element).isVisible().apply(browser)) {
throw new IllegalArgumentException("Element: " + element + " must be visible before interacting with it!");
}
}
private void executeEventOn(Event event, WebElement element) {
Utils.triggerJQ(executor, event.getEventName(), element);
}
private WebElement getHeaderElementDynamically(WebElement element) {
return element.findElement(By.cssSelector(advanced().getHeaderSelectorToInovkeEventOn()));
}
private void ensureElementExist(WebElement element) {
if (element == null) {
throw new IllegalArgumentException("Group/item must exist!");
}
}
}