/*
* JBoss, Home of Professional Open Source
* Copyright 2010-2016, 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.tests.metamer.ftest.extension.tester.attributes;
import static java.text.MessageFormat.format;
import static org.testng.Assert.assertTrue;
import java.util.AbstractMap.SimpleEntry;
import java.util.Map;
import java.util.Map.Entry;
import org.jboss.arquillian.graphene.Graphene;
import org.jboss.arquillian.graphene.enricher.JavaScriptEnricher;
import org.jboss.arquillian.graphene.javascript.JavaScript;
import org.openqa.selenium.interactions.Action;
import org.richfaces.fragment.common.Utils;
import org.richfaces.tests.metamer.ftest.AbstractWebDriverTest.ActionWrapper;
import org.richfaces.tests.metamer.ftest.extension.tester.attributes.MultipleAttributesSetter.MultipleAttributesToValueSetter;
import org.richfaces.tests.metamer.ftest.extension.tester.basic.TestResourcesProvider;
import com.google.common.collect.Maps;
/**
* @author <a href="mailto:jstefek@redhat.com">Jiri Stefek</a>
*/
public class AttributesHandler implements AttributesGetter, MultipleAttributesSetter, MultipleAttributesToValueSetter, Action {
private static final String EMPTY_STRING = "";
private static final String FOR_STRING = "FOR";
private static final int TRIES = 5;
@JavaScript
private AttributesSetter jsInterface;
private Entry<String, String> proposal;
private final TestResourcesProvider resourcesProvider;
private final JavaScriptEnricher scriptEnricher;
private final Action submitAction = new ActionWrapper(new Action() {
@Override
public void perform() {
getJsInterface().submit();
}
});
private final Map<String, String> toSet = Maps.newLinkedHashMap();
public AttributesHandler(TestResourcesProvider resourcesProvider) {
this.resourcesProvider = resourcesProvider;
scriptEnricher = new JavaScriptEnricher();
}
private static String lowerCaseForIfDetected(String attributeName) {
return attributeName.equals(FOR_STRING) ? attributeName.toLowerCase() : attributeName;
}
private void _perform() {
// set
for (Entry<String, String> entry : toSet.entrySet()) {
getJsInterface().setAttribute(entry.getKey(), entry.getValue());
}
if (getJsInterface().isDirty()) {
// submit
Graphene.guardHttp(submitAction).perform();
// check
for (Entry<String, String> entry : toSet.entrySet()) {
assertTrue(getJsInterface().checkAttributeIsSetToValue(entry.getKey(), entry.getValue()));
}
}
// slower implementation:
// final String[] names = toSet.keySet().toArray(new String[toSet.size()]);
// final String[] values = toSet.values().toArray(new String[toSet.size()]);
// getJsInterface().setAttributes(names, values);
// if (getJsInterface().isDirty()) {
// // submit
// Graphene.guardHttp(submitAction).perform();
// // check
// assertTrue(getJsInterface().checkAttributesAreSetToValues(names, values));
// }
}
@Override
public Action asSingleAction() {
return this;
}
@Override
public MultipleAttributesSetter clear() {
toSet.clear();
proposal = null;
return this;
}
@Override
public String getAttribute(String attributeName) {
return getAttribute(attributeName, EMPTY_STRING);
}
@Override
public String getAttribute(Object attributeName) {
return getAttribute(String.valueOf(attributeName));
}
@Override
public String getAttribute(String attributeName, String attributeTableID) {
return getJsInterface().getAttribute(format("{0}:{1}", attributeTableID, lowerCaseForIfDetected(attributeName)));
}
@Override
public String getAttribute(Object attributeName, String attributeTableID) {
return getAttribute(String.valueOf(attributeName), attributeTableID);
}
public AttributesSetter getJsInterface() {
if (jsInterface == null) {
scriptEnricher.enrich(resourcesProvider.getWebDriver().findElement(Utils.BY_BODY), this);
}
return jsInterface;
}
@Override
public boolean hasAttribute(String attributeName) {
return hasAttribute(attributeName, EMPTY_STRING);
}
@Override
public boolean hasAttribute(String attributeName, String attributeTableID) {
return getJsInterface().hasAttribute(format("{0}:{1}", attributeTableID, lowerCaseForIfDetected(attributeName)));
}
@Override
public boolean hasAttribute(Object attributeName) {
return hasAttribute(String.valueOf(attributeName), EMPTY_STRING);
}
@Override
public boolean hasAttribute(Object attributeName, String attributeTableID) {
return hasAttribute(String.valueOf(attributeName), attributeTableID);
}
@Override
public void perform() {
Throwable t = null;
for (int i = 0; i < TRIES; i++) {
try {
_perform();
return;
} catch (Throwable ex) {
t = ex;
}
}
throw new AttributeNotSetException(t);
}
@Override
public MultipleAttributesToValueSetter setAttribute(String attributeName) {
return setAttribute(attributeName, EMPTY_STRING);
}
@Override
public MultipleAttributesToValueSetter setAttribute(String attributeName, String attributeTableID) {
proposal = new SimpleEntry<String, String>(format("{0}:{1}", attributeTableID, lowerCaseForIfDetected(attributeName)), null);
return this;
}
@Override
public MultipleAttributesToValueSetter setAttribute(Object attributeName) {
return setAttribute(String.valueOf(attributeName));
}
@Override
public MultipleAttributesToValueSetter setAttribute(Object attributeName, String attributeTableID) {
return setAttribute(String.valueOf(attributeName), attributeTableID);
}
@Override
public MultipleAttributesSetter toValue(Object value) {
return toValue(String.valueOf(value));
}
@Override
public MultipleAttributesSetter toValue(String value) {
if (proposal == null) {
throw new IllegalStateException();
}
proposal.setValue(String.valueOf(value));
toSet.put(proposal.getKey(), proposal.getValue());
proposal = null;
return this;
}
@JavaScript(value = "Metamer.AttributesSetter")
public interface AttributesSetter {
boolean checkAttributeIsSetToValue(String name, String value);
boolean checkAttributesAreSetToValues(String[] names, String[] values);
String getAttribute(String name);
boolean hasAttribute(String name);
boolean isDirty();
void setAttribute(String name, String value);
void setAttributes(String[] names, String[] values);
void submit();
}
}