Skip to content

Commit

Permalink
Refactored BrowserStack support
Browse files Browse the repository at this point in the history
  • Loading branch information
wakaleo committed Dec 21, 2019
2 parents 8ab770f + 10fa1ec commit 817c3c4
Show file tree
Hide file tree
Showing 7 changed files with 340 additions and 273 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.serenitybdd.browserstack;

import net.serenitybdd.core.environment.EnvironmentSpecificConfiguration;
import net.serenitybdd.core.webdriver.OverrideDriverCapabilities;
import net.serenitybdd.core.webdriver.driverproviders.CapabilityValue;
import net.serenitybdd.core.webdriver.enhancers.BeforeAWebdriverScenario;
import net.thucydides.core.model.TestOutcome;
Expand All @@ -19,6 +20,7 @@ public class BeforeABrowserStackScenario implements BeforeAWebdriverScenario {

private static final String BROWSERSTACK = "browserstack.";
private static final Map<String, String> LEGACY_TO_W3C = new HashMap<>();
private static final List<String> UNOVERRIDABLE_FIELDS = Arrays.asList("browserstack.user", "browserstack.key","browserstack.server");

static {
LEGACY_TO_W3C.put("os_version", "osVersion");
Expand Down Expand Up @@ -56,40 +58,58 @@ public DesiredCapabilities apply(EnvironmentVariables environmentVariables,
capabilities.setPlatform(Platform.valueOf(remotePlatform));
}

Properties browserStackProperties = environmentVariables.getPropertiesWithPrefix(BROWSERSTACK);
Properties browserStackProperties = EnvironmentSpecificConfiguration
.from(environmentVariables)
.getPropertiesWithPrefix(BROWSERSTACK);

setNonW3CCapabilities(capabilities, browserStackProperties);
Properties browserStackPropertiesWithOverrides = caterForOverridesIn(browserStackProperties);
OverrideDriverCapabilities.in(browserStackPropertiesWithOverrides);

List<String> w3cProperties = browserStackProperties.stringPropertyNames()
.stream()
.filter(this::isW3CProperty)
.map(this::w3cKey)
.collect(Collectors.toList());
setNonW3CCapabilities(capabilities, browserStackPropertiesWithOverrides);

Map<String, Object> browserstackOptions = w3CPropertyMapFrom(browserStackProperties);
Map<String, Object> browserstackOptions = w3CPropertyMapFrom(browserStackPropertiesWithOverrides);
String testName = testOutcome.getStoryTitle() + " - " + testOutcome.getTitle();
browserstackOptions.put("sessionName", testName);

capabilities.setCapability("bstack:options", browserstackOptions);
return capabilities;
}

private Properties caterForOverridesIn(Properties browserStackProperties) {
Properties propertiesWithOverrides = new Properties();
browserStackProperties
.stringPropertyNames()
.stream()
.filter(this::shouldNotOveride)
.forEach(
name -> propertiesWithOverrides.put(name, browserStackProperties.getProperty(name))
);

return propertiesWithOverrides;
}

private void setNonW3CCapabilities(DesiredCapabilities capabilities, Properties browserStackProperties) {
browserStackProperties.stringPropertyNames()
.stream()
.filter(this::isNonW3CProperty)
.filter(this::shouldNotOveride)
.forEach(
key -> capabilities.setCapability(w3cKey(key), browserStackProperties.getProperty(key))
);
}

private boolean shouldNotOveride(String propertyName) {
return (!OverrideDriverCapabilities.shouldOverrideDefaults() || UNOVERRIDABLE_FIELDS.contains(propertyName));
}

private Map<String, Object> w3CPropertyMapFrom(Properties properties) {
Map<String, Object> w3cOptions = new HashMap<>();
Map<String,Map<String, Object>> nestedOptions = new HashMap<>();

properties.stringPropertyNames()
.stream()
.filter(this::isW3CProperty)
.filter(this::shouldNotOveride)
.forEach(
key -> {
String unprefixedKey = unprefixed(key);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package net.serenitybdd.core.webdriver;


import org.openqa.selenium.remote.DesiredCapabilities;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;

/**
* This class allows you to override driver capabilities defined in the Serenity configuration files at runtime.
Expand All @@ -17,28 +23,60 @@
public class OverrideDriverCapabilities {

private static ThreadLocal<Map<String,Object>> OVERRIDDEN_DRIVER_CAPABILITIES = ThreadLocal.withInitial(HashMap::new);
private static ThreadLocal<Boolean> OVERRIDE_DEFAULTS = ThreadLocal.withInitial(() -> FALSE);

public static OverrideDriverCapabilitiesBuilder withProperty(String propertyName) {
public static OverrideSetter withProperty(String propertyName) {
return new OverrideDriverCapabilitiesBuilder(propertyName);
}

public static void clear() {
OVERRIDDEN_DRIVER_CAPABILITIES.get().clear();
OVERRIDE_DEFAULTS.set(FALSE);
}

public static Map<String, Object> getProperties() {
return new HashMap<>(OVERRIDDEN_DRIVER_CAPABILITIES.get());
}

public static class OverrideDriverCapabilitiesBuilder {
public static void in(Properties properties) {
OverrideDriverCapabilities.getProperties().forEach(
(key, value) -> properties.setProperty(key,value.toString())
);
}

public static boolean shouldOverrideDefaults() {
return OVERRIDE_DEFAULTS.get();
}

public interface OverrideSetter {
CapabilityBuilderChain setTo(Object value);
}

public interface CapabilityBuilderChain {
OverrideSetter andProperty(String propertyName);
CapabilityBuilderChain andOverrideDefaults();
}

public static class OverrideDriverCapabilitiesBuilder implements OverrideSetter, CapabilityBuilderChain {
private String propertyName;

public OverrideDriverCapabilitiesBuilder(String propertyName) {
OverrideDriverCapabilitiesBuilder(String propertyName) {
this.propertyName = propertyName;
}

public void setTo(Object value) {
public CapabilityBuilderChain setTo(Object value) {
OVERRIDDEN_DRIVER_CAPABILITIES.get().put(propertyName, value);
return this;
}

public CapabilityBuilderChain andOverrideDefaults() {
OVERRIDE_DEFAULTS.set(TRUE);
return this;
}

public OverrideSetter andProperty(String propertyName) {
this.propertyName = propertyName;
return this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,8 @@ public void testFinished(final TestOutcome outcome, boolean inDataDrivenTest) {
testAndTopLevelStepsShouldBeIgnored();
}

OverrideDriverCapabilities.clear();

if (currentTestIsABrowserTest()) {
getCurrentTestOutcome().setDriver(getDriverUsedInThisTest());
updateSessionIdIfKnown();
Expand All @@ -520,8 +522,6 @@ public void testFinished(final TestOutcome outcome, boolean inDataDrivenTest) {
outcome,
SerenityWebdriverManager.inThisTestThread().getCurrentDriver());

OverrideDriverCapabilities.clear();

if (inDataDrivenTest) {
closeBrowsers.forTestSuite(testSuite).closeIfConfiguredForANew(EXAMPLE);
} else {
Expand Down Expand Up @@ -1127,6 +1127,7 @@ public void exampleFinished() {
if (latestTestOutcome().isPresent()) {
latestTestOutcome().get().moveToNextRow();
}
OverrideDriverCapabilities.clear();
if (currentTestIsABrowserTest()) {
getCurrentTestOutcome().setDriver(getDriverUsedInThisTest());
// updateSessionIdIfKnown();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,11 @@ public DesiredCapabilities enhanced(DesiredCapabilities capabilities, SupportedW
Optional<TestOutcome> currentTestOutcome = StepEventBus.getEventBus()
.getBaseStepListener()
.latestTestOutcome();

TestOutcome outcome = (currentTestOutcome == null) ? null : currentTestOutcome.orElse(null);
AddCustomDriverCapabilities.from(environmentVariables)
.withTestDetails(driver, outcome)
.to(capabilities);

OverrideDriverCapabilities.getProperties().forEach(
(key, value) -> capabilities.setCapability(key, value)
currentTestOutcome.ifPresent(
outcome -> AddCustomDriverCapabilities.from(environmentVariables)
.withTestDetails(driver, outcome)
.to(capabilities)
);
// TODO: Add programmatically-defined driver capabilities
}

return capabilities;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import net.thucydides.core.util.EnvironmentVariables;

import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand All @@ -11,6 +13,19 @@ public class EnvironmentSpecificConfiguration {
private EnvironmentVariables environmentVariables;
private EnvironmentStrategy environmentStrategy;

public Properties getPropertiesWithPrefix(String prefix) {
Set<String> propertyNames = environmentVariables.getPropertiesWithPrefix(prefix).stringPropertyNames();
Properties propertiesWithPrefix = new Properties();
propertyNames.forEach(
propertyName -> {
getOptionalProperty(propertyName).ifPresent(
propertyValue -> propertiesWithPrefix.setProperty(propertyName, propertyValue)
);
}
);
return propertiesWithPrefix;
}

enum EnvironmentStrategy {
USE_NORMAL_PROPERTIES,
USE_DEFAULT_PROPERTIES,
Expand Down
Loading

0 comments on commit 817c3c4

Please sign in to comment.