net.thucydides.core.webdriver.CapabilitySet Maven / Gradle / Ivy
package net.thucydides.core.webdriver;
import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
import net.thucydides.model.util.EnvironmentVariables;
import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
import java.util.Map;
import static net.thucydides.model.ThucydidesSystemProperty.SERENITY_DRIVER_CAPABILITIES;
/**
* A set of user-defined capabilities to be used to configure the WebDriver driver.
* Capabilities should be passed in as a semi-colon-separated list of key:value pairs, e.g.
* "build:build-1234; max-duration:300; single-window:true; tags:[tag1,tag2,tag3]"
*/
class CapabilitySet {
private final EnvironmentVariables environmentVariables;
private static final CharMatcher CAPABILITY_SEPARATOR = CharMatcher.anyOf(";");
CapabilitySet(EnvironmentVariables environmentVariables) {
this.environmentVariables = environmentVariables.copy();
}
public Map getCapabilities() {
Map capabilitiesMap = new HashMap<>();
String specifiedCapabilities = SERENITY_DRIVER_CAPABILITIES.from(environmentVariables);
if (StringUtils.isNotEmpty(specifiedCapabilities)) {
Iterable capabilityValues = Splitter.on(CAPABILITY_SEPARATOR).trimResults().split(specifiedCapabilities);
capabilitiesMap = addCapabilityMapValues(capabilityValues);
}
return capabilitiesMap;
}
private Map addCapabilityMapValues(Iterable capabilityValues) {
Map capabilitiesMap = new HashMap<>();
for(String capability : capabilityValues) {
CapabilityToken token = new CapabilityToken(capability);
if (token.isDefined()) {
capabilitiesMap.put(token.getName(), CapabilityValue.asObject(token.getValue()));
}
}
return capabilitiesMap;
}
private static class CapabilityToken {
private final String name;
private final String value;
private CapabilityToken(String capability) {
int colonIndex = capability.lastIndexOf(":");
if (colonIndex >= 0) {
boolean colonIndexFound = false;
int lastIndex = capability.length();
while(!colonIndexFound) {
int lastColonIndex = capability.lastIndexOf(":", lastIndex);
if (lastColonIndex > 0) {
colonIndex = lastColonIndex;
// Check if colon is part of file path or JSON object
if ((capability.length() >= colonIndex + 1)
&& (isFollowedByPathSeparator(capability, colonIndex) || isWithinJsonObject(capability, colonIndex))) {
if (lastIndex == colonIndex - 1) {
colonIndexFound = true;
//been here before, only single colon followed by a path separator found
break;
}
lastIndex = colonIndex - 1;
} else {
colonIndexFound = true;
}
}
else {
colonIndexFound = true;
}
}
name = capability.substring(0, colonIndex);
value = capability.substring(colonIndex + 1);
} else {
name = capability;
value = null;
}
}
private boolean isFollowedByPathSeparator(String capability, int colonIndex) {
return (capability.charAt(colonIndex+1) =='\\') || (capability.charAt(colonIndex+1) =='/');
}
/**
* Check if colon is between opening and closing curly brackets
*/
private boolean isWithinJsonObject(String capability, int colonIndex) {
int openingBracketIndex = capability.indexOf('{');
int closingBracketIndex = capability.indexOf('}');
return (openingBracketIndex > 0) && (openingBracketIndex < colonIndex) && (colonIndex < closingBracketIndex);
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
public boolean isDefined() {
return (StringUtils.isNotEmpty(name) && StringUtils.isNotEmpty(value));
}
}
}