diff --git a/browser-firefox.properties b/browser-firefox.properties new file mode 100644 index 0000000000..a36f0f45af --- /dev/null +++ b/browser-firefox.properties @@ -0,0 +1,4 @@ +# +#Thu Feb 12 13:47:25 EST 2015 +version= +browserName=firefox diff --git a/browser-htmlUnit.properties b/browser-htmlUnit.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/core/build.gradle b/core/build.gradle index 0b3d837139..aa2b5f9bdc 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -49,6 +49,8 @@ dependencies { compile 'io.appium:java-client:2.1.0' + compile 'org.codehaus.groovy:groovy:2.4.0' + compile "net.sf.opencsv:opencsv:2.0" compile ("commons-beanutils:commons-beanutils-core:1.8.3") { exclude group: 'commons-logging', module: 'commons-logging' diff --git a/core/src/main/java/net/serenitybdd/core/buildinfo/BuildInfoProvider.java b/core/src/main/java/net/serenitybdd/core/buildinfo/BuildInfoProvider.java new file mode 100644 index 0000000000..c72c1c0c19 --- /dev/null +++ b/core/src/main/java/net/serenitybdd/core/buildinfo/BuildInfoProvider.java @@ -0,0 +1,72 @@ +package net.serenitybdd.core.buildinfo; + +import com.beust.jcommander.internal.Maps; +import groovy.lang.Binding; +import groovy.lang.GroovyShell; +import net.thucydides.core.ThucydidesSystemProperty; +import net.thucydides.core.guice.Injectors; +import net.thucydides.core.guice.ThucydidesModule; +import net.thucydides.core.util.EnvironmentVariables; + +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import static ch.lambdaj.Lambda.filter; +import static org.hamcrest.CoreMatchers.startsWith; + +/** + * Created by john on 12/02/15. + */ +public class BuildInfoProvider { + private final EnvironmentVariables environmentVariables; + private final DriverCapabilityRecord driverCapabilityRecord; + + public BuildInfoProvider(EnvironmentVariables environmentVariables) { + this.environmentVariables = environmentVariables; + this.driverCapabilityRecord = Injectors.getInjector().getInstance(DriverCapabilityRecord.class); + } + + public BuildProperties getBuildProperties() { + Map generalProperties = Maps.newHashMap(); + generalProperties.put("Default Driver",ThucydidesSystemProperty.DRIVER.from(environmentVariables,"firefox")); + generalProperties.put("Operating System",System.getProperty("os.name") + " version " + System.getProperty("os.version")); + addRemoteDriverPropertiesTo(generalProperties); + addCustomPropertiesTo(generalProperties); + + List drivers = driverCapabilityRecord.getDrivers(); + Map driverPropertiesMap = driverCapabilityRecord.getDriverCapabilities(); + + return new BuildProperties(generalProperties, drivers, driverPropertiesMap); + } + + private void addRemoteDriverPropertiesTo(Map buildProperties) { + if (ThucydidesSystemProperty.WEBDRIVER_REMOTE_DRIVER.isDefinedIn(environmentVariables)) { + buildProperties.put("Remote driver", ThucydidesSystemProperty.WEBDRIVER_REMOTE_DRIVER.from(environmentVariables)); + buildProperties.put("Remote browser version", ThucydidesSystemProperty.WEBDRIVER_REMOTE_BROWSER_VERSION.from(environmentVariables)); + buildProperties.put("Remote OS", ThucydidesSystemProperty.WEBDRIVER_REMOTE_OS.from(environmentVariables)); + } + } + + private void addCustomPropertiesTo(Map buildProperties) { + + List sysInfoKeys = filter(startsWith("sysinfo."), environmentVariables.getKeys()); + for(String key : sysInfoKeys) { + String simplifiedKey = key.replace("sysinfo.", ""); + String expression = environmentVariables.getProperty(key); + + String value = evaluateGroovyExpression(expression); + + buildProperties.put(simplifiedKey, value); + } + + } + + private String evaluateGroovyExpression(String expression) { + Binding binding = new Binding(); + binding.setVariable("env", environmentVariables); + GroovyShell shell = new GroovyShell(binding); + return shell.evaluate(expression).toString(); + } + +} diff --git a/core/src/main/java/net/serenitybdd/core/buildinfo/BuildProperties.java b/core/src/main/java/net/serenitybdd/core/buildinfo/BuildProperties.java new file mode 100644 index 0000000000..398ecd68a9 --- /dev/null +++ b/core/src/main/java/net/serenitybdd/core/buildinfo/BuildProperties.java @@ -0,0 +1,36 @@ +package net.serenitybdd.core.buildinfo; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +import java.util.List; +import java.util.Map; +import java.util.Properties; + +/** + * Created by john on 12/02/15. + */ +public class BuildProperties { + + private final Map generalProperties; + private final List drivers; + private final Map driverProperties; + + public BuildProperties(Map generalProperties, List drivers, Map driverProperties) { + this.generalProperties = generalProperties; + this.drivers = drivers; + this.driverProperties = driverProperties; + } + + public Map getGeneralProperties() { + return ImmutableMap.copyOf(generalProperties); + } + + public List getDrivers() { + return ImmutableList.copyOf(drivers); + } + + public Map getDriverProperties() { + return ImmutableMap.copyOf(driverProperties); + } +} diff --git a/core/src/main/java/net/serenitybdd/core/buildinfo/DriverCapabilityRecord.java b/core/src/main/java/net/serenitybdd/core/buildinfo/DriverCapabilityRecord.java new file mode 100644 index 0000000000..4541564745 --- /dev/null +++ b/core/src/main/java/net/serenitybdd/core/buildinfo/DriverCapabilityRecord.java @@ -0,0 +1,16 @@ +package net.serenitybdd.core.buildinfo; + +import org.openqa.selenium.Capabilities; + +import java.util.List; +import java.util.Map; +import java.util.Properties; + +/** + * Created by john on 12/02/15. + */ +public interface DriverCapabilityRecord { + void registerCapabilities(String driver, Capabilities capabilities); + List getDrivers(); + Map getDriverCapabilities(); +} diff --git a/core/src/main/java/net/serenitybdd/core/buildinfo/PropertyBasedDriverCapabilityRecord.java b/core/src/main/java/net/serenitybdd/core/buildinfo/PropertyBasedDriverCapabilityRecord.java new file mode 100644 index 0000000000..025d4a73c2 --- /dev/null +++ b/core/src/main/java/net/serenitybdd/core/buildinfo/PropertyBasedDriverCapabilityRecord.java @@ -0,0 +1,90 @@ +package net.serenitybdd.core.buildinfo; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.inject.Inject; +import net.thucydides.core.webdriver.Configuration; +import org.openqa.selenium.Capabilities; + +import java.io.*; +import java.nio.file.DirectoryIteratorException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import static java.nio.file.Files.newInputStream; + +/** + * Created by john on 12/02/15. + */ +public class PropertyBasedDriverCapabilityRecord implements DriverCapabilityRecord { + + private Configuration configuration; + + @Inject + public PropertyBasedDriverCapabilityRecord(Configuration configuration) { + this.configuration = configuration; + } + + public void registerCapabilities(String driver, Capabilities capabilities) { + + Properties properties = new Properties(); + properties.setProperty("platform", capabilities.getPlatform().name()); + for (String capability : capabilities.asMap().keySet()) { + if (capabilities.getCapability(capability) instanceof String) { + properties.setProperty(capability, capabilities.getCapability(capability).toString()); + } + } + try { + File browserProperties = new File(configuration.getOutputDirectory(), "browser-" + driver.toLowerCase() + ".properties"); + try (Writer writer = new FileWriter(browserProperties)) { + properties.store(writer, ""); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public List getDrivers() { + List drivers = Lists.newArrayList(); + try (DirectoryStream stream = driverCapabilityRecords()) { + for (Path file : stream) { + String driverName = driverNameFrom(file); + drivers.add(driverName); + } + } catch (IOException | DirectoryIteratorException x) { + System.err.println(x); + } + return drivers; + } + + private String driverNameFrom(Path file) { + return file.getFileName().toString().replace("browser-","").replace(".properties",""); + } + + private DirectoryStream driverCapabilityRecords() throws IOException { + Path outputDirectory = configuration.getOutputDirectory().toPath(); + return Files.newDirectoryStream(outputDirectory,"browser-*.properties"); + } + + @Override + public Map getDriverCapabilities() { + Map driverCapabilities = Maps.newHashMap(); + try (DirectoryStream stream = driverCapabilityRecords()) { + for (Path file : stream) { + String driverName = driverNameFrom(file); + Properties driverProperties = new Properties(); + driverProperties.load(newInputStream(file)); + driverCapabilities.put(driverName, driverProperties); + } + } catch (IOException | DirectoryIteratorException x) { + System.err.println(x); + } + return driverCapabilities; + } + +} diff --git a/core/src/main/java/net/thucydides/core/guice/ThucydidesModule.java b/core/src/main/java/net/thucydides/core/guice/ThucydidesModule.java index f013bb1324..bad9559baf 100644 --- a/core/src/main/java/net/thucydides/core/guice/ThucydidesModule.java +++ b/core/src/main/java/net/thucydides/core/guice/ThucydidesModule.java @@ -3,6 +3,8 @@ import com.google.inject.AbstractModule; import com.google.inject.Provides; import com.google.inject.Singleton; +import net.serenitybdd.core.buildinfo.DriverCapabilityRecord; +import net.serenitybdd.core.buildinfo.PropertyBasedDriverCapabilityRecord; import net.thucydides.core.annotations.locators.SmartElementProxyCreator; import net.thucydides.core.batches.BatchManager; import net.thucydides.core.batches.BatchManagerProvider; @@ -66,6 +68,7 @@ protected void configure() { bind(TestCount.class).to(AtomicTestCount.class).in(Singleton.class); bind(MarkupRenderer.class).annotatedWith(Asciidoc.class).to(AsciidocMarkupRenderer.class).in(Singleton.class); + bind(DriverCapabilityRecord.class).to(PropertyBasedDriverCapabilityRecord.class); } @Provides diff --git a/core/src/main/java/net/thucydides/core/model/TestOutcome.java b/core/src/main/java/net/thucydides/core/model/TestOutcome.java index 8c4bf8a34f..8fb8a02d80 100644 --- a/core/src/main/java/net/thucydides/core/model/TestOutcome.java +++ b/core/src/main/java/net/thucydides/core/model/TestOutcome.java @@ -143,6 +143,11 @@ public class TestOutcome { */ private String sessionId; + /** + * The driver used to run this test if it is a web test. + */ + private String driver; + /** * Keeps track of step groups. * If not empty, the top of the stack contains the step corresponding to the current step group - new steps should @@ -313,6 +318,7 @@ public TestOutcome copy() { this.annotatedResult, this.dataTable, this.qualifier, + this.driver, this.manual); } @@ -333,6 +339,7 @@ protected TestOutcome(final Long startTime, final TestResult annotatedResult, final DataTable dataTable, final Optional qualifier, + final String driver, final boolean manualTest) { this.startTime = startTime; this.duration = duration; @@ -355,6 +362,7 @@ protected TestOutcome(final Long startTime, this.dataTable = dataTable; this.issueTracking = Injectors.getInjector().getInstance(IssueTracking.class); this.linkGenerator = Injectors.getInjector().getInstance(LinkGenerator.class); + this.driver = driver; this.manual = manualTest; } @@ -399,6 +407,7 @@ public TestOutcome withQualifier(String qualifier) { this.annotatedResult, this.dataTable, Optional.fromNullable(qualifier), + this.driver, this.manual); } else { return this; @@ -423,6 +432,7 @@ public TestOutcome withIssues(List issues) { this.annotatedResult, this.dataTable, this.qualifier, + this.driver, this.manual); } @@ -444,6 +454,7 @@ public TestOutcome withTags(Set tags) { this.annotatedResult, this.dataTable, this.qualifier, + this.driver, this.manual); } @@ -466,6 +477,7 @@ public TestOutcome withMethodName(String methodName) { this.annotatedResult, this.dataTable, this.qualifier, + this.driver, this.manual); } else { return this; @@ -545,6 +557,14 @@ public void clearForcedResult() { annotatedResult = null; } + public void setDriver(String driver) { + this.driver = driver; + } + + public String getDriver() { + return driver; + } + public class TitleBuilder { private final boolean qualified; private final TestOutcome testOutcome; diff --git a/core/src/main/java/net/thucydides/core/reports/html/HtmlAggregateStoryReporter.java b/core/src/main/java/net/thucydides/core/reports/html/HtmlAggregateStoryReporter.java index e1fdd00277..a2bce54746 100644 --- a/core/src/main/java/net/thucydides/core/reports/html/HtmlAggregateStoryReporter.java +++ b/core/src/main/java/net/thucydides/core/reports/html/HtmlAggregateStoryReporter.java @@ -1,7 +1,9 @@ package net.thucydides.core.reports.html; import com.beust.jcommander.internal.Lists; +import com.beust.jcommander.internal.Maps; import net.serenitybdd.core.SerenitySystemProperties; +import net.serenitybdd.core.buildinfo.BuildInfoProvider; import net.thucydides.core.ThucydidesSystemProperty; import net.thucydides.core.guice.Injectors; import net.thucydides.core.issues.IssueTracking; @@ -21,6 +23,7 @@ import net.thucydides.core.requirements.reports.RequirmentsOutcomeFactory; import net.thucydides.core.util.EnvironmentVariables; import net.thucydides.core.util.Inflector; +import net.thucydides.core.util.LocalPreferences; import net.thucydides.core.util.VersionProvider; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -44,6 +47,7 @@ public class HtmlAggregateStoryReporter extends HtmlReporter implements UserStor private static final String HISTORY_TEMPLATE_PATH = "freemarker/history.ftl"; private static final String TEST_OUTCOME_TEMPLATE_PATH = "freemarker/home.ftl"; + private static final String BUILD_INFO_TEMPLATE_PATH = "freemarker/build-info.ftl"; private static final String RELEASES_TEMPLATE_PATH = "freemarker/releases.ftl"; private static final String RELEASE_TEMPLATE_PATH = "freemarker/release.ftl"; private static final String TAGTYPE_TEMPLATE_PATH = "freemarker/results-by-tagtype.ftl"; @@ -115,6 +119,12 @@ private void addFormattersToContext(final Map context) { context.put("reportOptions", new ReportOptions(getEnvironmentVariables())); } + private void addBuildInformationToContext(final Map context) { + BuildInfoProvider buildInfoProvider = new BuildInfoProvider(getEnvironmentVariables()); + context.put("build", buildInfoProvider.getBuildProperties()); + } + + public TestOutcomes generateReportsForTestResultsFrom(final File sourceDirectory) throws IOException { TestOutcomes allTestOutcomes = loadTestOutcomesFrom(sourceDirectory); copyScreenshotsFrom(sourceDirectory); @@ -247,6 +257,7 @@ private void generateAggregateReportFor(TestOutcomes testOutcomes) throws IOExce context.put("csvReport", "results.csv"); generateReportPage(context, TEST_OUTCOME_TEMPLATE_PATH, "index.html"); + generateReportPage(context, BUILD_INFO_TEMPLATE_PATH, "build-info.html"); generateCSVReportFor(testOutcomes, "results.csv"); logReportPathMessage(); } @@ -471,6 +482,7 @@ private Map buildContext(TestOutcomes testOutcomesForTagType, context.put("serenityVersionNumber", versionProvider.getVersion()); context.put("buildNumber", versionProvider.getBuildNumberText()); + addBuildInformationToContext(context); return context; } diff --git a/core/src/main/java/net/thucydides/core/steps/BaseStepListener.java b/core/src/main/java/net/thucydides/core/steps/BaseStepListener.java index f93ce7200c..80e32308e2 100644 --- a/core/src/main/java/net/thucydides/core/steps/BaseStepListener.java +++ b/core/src/main/java/net/thucydides/core/steps/BaseStepListener.java @@ -14,10 +14,7 @@ import net.serenitybdd.core.pages.Pages; import net.serenitybdd.core.pages.SystemClock; import net.thucydides.core.screenshots.*; -import net.thucydides.core.webdriver.Configuration; -import net.thucydides.core.webdriver.WebDriverFacade; -import net.thucydides.core.webdriver.WebdriverManager; -import net.thucydides.core.webdriver.WebdriverProxyFactory; +import net.thucydides.core.webdriver.*; import org.apache.commons.lang3.StringUtils; import org.openqa.selenium.WebDriver; import org.openqa.selenium.remote.SessionId; @@ -269,6 +266,9 @@ public void testSuiteFinished() { */ public void testStarted(final String testMethod) { TestOutcome newTestOutcome = TestOutcome.forTestInStory(testMethod, testSuite, testedStory); + if (driver != null) { + newTestOutcome.setDriver(webdriverManager.getCurrentDriverName()); + } testOutcomes.add(newTestOutcome); updateSessionIdIfKnown(); setAnnotatedResult(testMethod); diff --git a/core/src/main/java/net/thucydides/core/webdriver/ThucydidesWebdriverManager.java b/core/src/main/java/net/thucydides/core/webdriver/ThucydidesWebdriverManager.java index 73bab77de2..6f5b7c7cca 100644 --- a/core/src/main/java/net/thucydides/core/webdriver/ThucydidesWebdriverManager.java +++ b/core/src/main/java/net/thucydides/core/webdriver/ThucydidesWebdriverManager.java @@ -95,7 +95,12 @@ public void resetDriver() { } public WebDriver getWebdriver() { - return getThreadLocalWebDriver(configuration, webDriverFactory, inThisTestThread().getCurrentDriverName()); + WebDriver driver = getThreadLocalWebDriver(configuration, webDriverFactory, inThisTestThread().getCurrentDriverName()); + return driver; + } + + public String getCurrentDriverName() { + return inThisTestThread().getCurrentDriverName(); } public SessionId getSessionId() { diff --git a/core/src/main/java/net/thucydides/core/webdriver/WebDriverFactory.java b/core/src/main/java/net/thucydides/core/webdriver/WebDriverFactory.java index aa76932b25..2bbede37da 100644 --- a/core/src/main/java/net/thucydides/core/webdriver/WebDriverFactory.java +++ b/core/src/main/java/net/thucydides/core/webdriver/WebDriverFactory.java @@ -260,7 +260,7 @@ private WebDriver newDriverInstanceFrom(Class driverClass) return webdriverInstanceFactory.newInstanceOf(driverClass); } - private WebDriver newRemoteDriver() throws MalformedURLException { + private WebDriver newRemoteDriver() throws MalformedURLException { WebDriver driver = null; if (saucelabsUrlIsDefined()) { diff --git a/core/src/main/java/net/thucydides/core/webdriver/WebdriverInstanceFactory.java b/core/src/main/java/net/thucydides/core/webdriver/WebdriverInstanceFactory.java index 68a70894c8..758496c25a 100644 --- a/core/src/main/java/net/thucydides/core/webdriver/WebdriverInstanceFactory.java +++ b/core/src/main/java/net/thucydides/core/webdriver/WebdriverInstanceFactory.java @@ -2,6 +2,8 @@ import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.ios.IOSDriver; +import net.serenitybdd.core.buildinfo.DriverCapabilityRecord; +import net.thucydides.core.guice.Injectors; import org.openqa.selenium.Capabilities; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; @@ -19,7 +21,10 @@ */ public class WebdriverInstanceFactory { + private DriverCapabilityRecord driverProperties; + public WebdriverInstanceFactory() { + this.driverProperties = Injectors.getInjector().getInstance(DriverCapabilityRecord.class); } public WebDriver newInstanceOf(final Class webdriverClass) throws IllegalAccessException, InstantiationException { @@ -27,40 +32,59 @@ public WebDriver newInstanceOf(final Class webdriverClass) } public WebDriver newRemoteDriver(URL remoteUrl, Capabilities capabilities) { - return new RemoteWebDriver(remoteUrl, capabilities); + RemoteWebDriver driver = new RemoteWebDriver(remoteUrl, capabilities); + driverProperties.registerCapabilities("remote", driver.getCapabilities()); + return driver; } public WebDriver newFirefoxDriver(Capabilities capabilities) { - return new FirefoxDriver(capabilities); + FirefoxDriver driver = new FirefoxDriver(capabilities); + driverProperties.registerCapabilities("firefox", driver.getCapabilities()); + return driver; } public WebDriver newChromeDriver(Capabilities capabilities) { - return new ChromeDriver(capabilities); + ChromeDriver driver = new ChromeDriver(capabilities); + driverProperties.registerCapabilities("chrome", driver.getCapabilities()); + return driver; } public WebDriver newAppiumDriver(URL hub, Capabilities capabilities, MobilePlatform platform) { switch (platform) { case ANDROID: - return new AndroidDriver(hub, capabilities); + AndroidDriver androidDriver = new AndroidDriver(hub, capabilities); + driverProperties.registerCapabilities("appium", androidDriver.getCapabilities()); + return androidDriver; case IOS: - return new IOSDriver(hub, capabilities); + IOSDriver iosDriver = new IOSDriver(hub, capabilities); + driverProperties.registerCapabilities("appium", iosDriver.getCapabilities()); + return iosDriver; } throw new UnsupportedDriverException(platform.name()); } public WebDriver newSafariDriver(Capabilities capabilities) { - return new SafariDriver(capabilities); + SafariDriver driver = new SafariDriver(capabilities); + driverProperties.registerCapabilities("chrome", driver.getCapabilities()); + return driver; } public WebDriver newInternetExplorerDriver(Capabilities capabilities) { - return new InternetExplorerDriver(capabilities); + InternetExplorerDriver driver = new InternetExplorerDriver(capabilities); + driverProperties.registerCapabilities("iexplorer", driver.getCapabilities()); + return driver; } public WebDriver newHtmlUnitDriver(Capabilities capabilities) { - return new HtmlUnitDriver(capabilities); + HtmlUnitDriver driver = new HtmlUnitDriver(capabilities); + driverProperties.registerCapabilities("htmlunit", driver.getCapabilities()); + return driver; } - public WebDriver newPhantomDriver(Capabilities caps) { - return new PhantomJSDriver(caps); + public WebDriver newPhantomDriver(Capabilities capabilities) { + PhantomJSDriver driver = new PhantomJSDriver(capabilities); + driverProperties.registerCapabilities("phantomjs", driver.getCapabilities()); + return driver; } + } \ No newline at end of file diff --git a/core/src/main/java/net/thucydides/core/webdriver/WebdriverInstances.java b/core/src/main/java/net/thucydides/core/webdriver/WebdriverInstances.java index a872515003..a6d4a3c65c 100644 --- a/core/src/main/java/net/thucydides/core/webdriver/WebdriverInstances.java +++ b/core/src/main/java/net/thucydides/core/webdriver/WebdriverInstances.java @@ -15,7 +15,7 @@ public class WebdriverInstances { private String currentDriver; public WebdriverInstances() { - this.driverMap = new HashMap(); + this.driverMap = new HashMap<>(); } public WebDriver getCurrentDriver() { diff --git a/core/src/main/java/net/thucydides/core/webdriver/WebdriverManager.java b/core/src/main/java/net/thucydides/core/webdriver/WebdriverManager.java index 2fed38e9f6..13d12ee837 100644 --- a/core/src/main/java/net/thucydides/core/webdriver/WebdriverManager.java +++ b/core/src/main/java/net/thucydides/core/webdriver/WebdriverManager.java @@ -17,6 +17,8 @@ public interface WebdriverManager { WebDriver getWebdriver(final String driver); + String getCurrentDriverName(); + SessionId getSessionId(); void closeDriver(); diff --git a/core/src/main/java/net/thucydides/core/webdriver/appium/AppiumConfiguration.java b/core/src/main/java/net/thucydides/core/webdriver/appium/AppiumConfiguration.java index bfea467190..1d418cf42a 100644 --- a/core/src/main/java/net/thucydides/core/webdriver/appium/AppiumConfiguration.java +++ b/core/src/main/java/net/thucydides/core/webdriver/appium/AppiumConfiguration.java @@ -53,13 +53,18 @@ public URL getUrl() { public DesiredCapabilities getCapabilities() { DesiredCapabilities capabilities = new DesiredCapabilities(); - Properties appiumProperties = appiumPropertiesFrom(environmentVariables); + Properties appiumProperties = getProperties(); for (Object key : appiumProperties.keySet()) { capabilities.setCapability(key.toString(), appiumProperties.getProperty(key.toString())); + capabilities.asMap(); } return capabilities; } + public Properties getProperties() { + return appiumPropertiesFrom(environmentVariables); + } + private Properties appiumPropertiesFrom(EnvironmentVariables environmentVariables) { Properties appiumProperties = new Properties(); List appiumKeys = filter(startsWith("appium."), environmentVariables.getKeys()); diff --git a/core/src/test/groovy/net/serenitybdd/core/buildinfo/WhenStoringAndRetrievingDriverCapabilities.groovy b/core/src/test/groovy/net/serenitybdd/core/buildinfo/WhenStoringAndRetrievingDriverCapabilities.groovy new file mode 100644 index 0000000000..598311c1f9 --- /dev/null +++ b/core/src/test/groovy/net/serenitybdd/core/buildinfo/WhenStoringAndRetrievingDriverCapabilities.groovy @@ -0,0 +1,48 @@ +package net.serenitybdd.core.buildinfo + +import com.github.goldin.spock.extensions.tempdir.TempDir +import net.thucydides.core.webdriver.Configuration +import org.openqa.selenium.remote.DesiredCapabilities +import spock.lang.Specification + +/** + * Created by john on 12/02/15. + */ +class WhenStoringAndRetrievingDriverCapabilities extends Specification { + + @TempDir File outputDirectory + + + def configuration = Mock(Configuration) + + def setup() { + configuration.getOutputDirectory() >> outputDirectory + } + + def "should store driver capabilities as property files"() { + given: + def driverCapabilityRecord = new PropertyBasedDriverCapabilityRecord(configuration) + when: + driverCapabilityRecord.registerCapabilities("htmlUnit", DesiredCapabilities.htmlUnit()); + driverCapabilityRecord.registerCapabilities("firefox", DesiredCapabilities.firefox()); + then: + outputDirectory.list() == ["browser-firefox.properties","browser-htmlunit.properties"] + } + + def "should read driver capabilities from stored properties files"() { + given: + def driverCapabilityRecord = new PropertyBasedDriverCapabilityRecord(configuration) + and: + driverCapabilityRecord.registerCapabilities("htmlUnit", DesiredCapabilities.htmlUnit()); + driverCapabilityRecord.registerCapabilities("firefox", DesiredCapabilities.firefox()); + when: + def drivers = driverCapabilityRecord.drivers + def capabilities = driverCapabilityRecord.driverCapabilities + then: + drivers == ["firefox","htmlunit"] + and: + capabilities["firefox"].getProperty("browserName") == "firefox" + capabilities["htmlunit"].getProperty("browserName") == "htmlunit" + + } +} diff --git a/core/src/test/resources/test-outcomes/containing-features-and-stories/browser-chrome.properties b/core/src/test/resources/test-outcomes/containing-features-and-stories/browser-chrome.properties new file mode 100644 index 0000000000..92f8592ea5 --- /dev/null +++ b/core/src/test/resources/test-outcomes/containing-features-and-stories/browser-chrome.properties @@ -0,0 +1,4 @@ +# +#Thu Feb 12 14:05:13 EST 2015 +version= +browserName=chrome diff --git a/core/src/test/resources/test-outcomes/containing-features-and-stories/browser-firefox.properties b/core/src/test/resources/test-outcomes/containing-features-and-stories/browser-firefox.properties new file mode 100644 index 0000000000..f28f7fe0b5 --- /dev/null +++ b/core/src/test/resources/test-outcomes/containing-features-and-stories/browser-firefox.properties @@ -0,0 +1,4 @@ +# +#Thu Feb 12 14:04:26 EST 2015 +version= +browserName=firefox diff --git a/core/src/test/resources/test-outcomes/full-json/browser-chrome.properties b/core/src/test/resources/test-outcomes/full-json/browser-chrome.properties new file mode 100644 index 0000000000..92f8592ea5 --- /dev/null +++ b/core/src/test/resources/test-outcomes/full-json/browser-chrome.properties @@ -0,0 +1,4 @@ +# +#Thu Feb 12 14:05:13 EST 2015 +version= +browserName=chrome diff --git a/core/src/test/resources/test-outcomes/full-json/browser-firefox.properties b/core/src/test/resources/test-outcomes/full-json/browser-firefox.properties new file mode 100644 index 0000000000..f28f7fe0b5 --- /dev/null +++ b/core/src/test/resources/test-outcomes/full-json/browser-firefox.properties @@ -0,0 +1,4 @@ +# +#Thu Feb 12 14:04:26 EST 2015 +version= +browserName=firefox diff --git a/serenity-report-resources/src/main/resources/freemarker/build-info.ftl b/serenity-report-resources/src/main/resources/freemarker/build-info.ftl new file mode 100644 index 0000000000..6ed1872398 --- /dev/null +++ b/serenity-report-resources/src/main/resources/freemarker/build-info.ftl @@ -0,0 +1,243 @@ + + + + + + + + + Serenity Reports + + + +<#include "libraries/common.ftl"> +<#include "libraries/jquery-ui.ftl"> +<#include "libraries/datatables.ftl"> +<#assign pie = true> +<#include "libraries/jqplot.ftl"> + +<#assign successfulManualTests = (testOutcomes.count("manual").withResult("SUCCESS") > 0)> +<#assign pendingManualTests = (testOutcomes.count("manual").withResult("PENDING") > 0)> +<#assign ignoredManualTests = (testOutcomes.count("manual").withResult("IGNORED") > 0)> +<#assign failingManualTests = (testOutcomes.count("manual").withResult("FAILURE") > 0)> + + + + + +
+
+ +
+ ${reportOptions.projectName} +
+
+
+ +
+ +
+ <#--
--> +
+ Home +
+
+
+ +
+ + +<#include "menu.ftl"> +<@main_menu selected="home" /> +
+
+
+
+
+

Build Information

+ + <#assign keys = build.generalProperties?keys> + + <#list keys as key> + + + + + +
${key}${build.generalProperties[key]}
+ + <#assign drivers = build.drivers> + <#list drivers as driver> +

Driver capabilities: ${driver}

+ <#assign driverCapabilities = build.driverProperties[driver]> + <#assign capabilityKeys = driverCapabilities?keys> + + <#list capabilityKeys as capability> + + + + +
${capability}${driverCapabilities[capability]}
+ + + +
+ <#--- Test Results end --> +
+
+
+ +
+
+ Serenity version ${serenityVersionNumber} +
+ + + diff --git a/serenity-report-resources/src/main/resources/freemarker/default.ftl b/serenity-report-resources/src/main/resources/freemarker/default.ftl index d80e814373..3d4fd465c5 100644 --- a/serenity-report-resources/src/main/resources/freemarker/default.ftl +++ b/serenity-report-resources/src/main/resources/freemarker/default.ftl @@ -72,6 +72,9 @@ ${testOutcome.formattedIssues} + <#if (testOutcome.driver)??> + ${testOutcome.driver} + diff --git a/serenity-report-resources/src/main/resources/freemarker/menu.ftl b/serenity-report-resources/src/main/resources/freemarker/menu.ftl index da89af95fb..6e7c808b3a 100644 --- a/serenity-report-resources/src/main/resources/freemarker/menu.ftl +++ b/serenity-report-resources/src/main/resources/freemarker/menu.ftl @@ -40,7 +40,7 @@ - Report generated ${timestamp} + Report generated ${timestamp}
\ No newline at end of file diff --git a/serenity-report-resources/src/main/resources/report-resources/css/core.css b/serenity-report-resources/src/main/resources/report-resources/css/core.css index c185f0b5cf..5a13643fc1 100644 --- a/serenity-report-resources/src/main/resources/report-resources/css/core.css +++ b/serenity-report-resources/src/main/resources/report-resources/css/core.css @@ -1416,3 +1416,11 @@ ul.second-level-requirements { color: #0d78ae; border: none; } + +.build-info table { + table-layout: fixed; +} + +.build-info table td,th { + overflow: hidden; +} \ No newline at end of file diff --git a/serenity-report-resources/src/main/resources/report-resources/images/driver-appium.png b/serenity-report-resources/src/main/resources/report-resources/images/driver-appium.png new file mode 100644 index 0000000000..cddbc84086 Binary files /dev/null and b/serenity-report-resources/src/main/resources/report-resources/images/driver-appium.png differ diff --git a/serenity-report-resources/src/main/resources/report-resources/images/driver-chrome.png b/serenity-report-resources/src/main/resources/report-resources/images/driver-chrome.png new file mode 100644 index 0000000000..deb51d0b58 Binary files /dev/null and b/serenity-report-resources/src/main/resources/report-resources/images/driver-chrome.png differ diff --git a/serenity-report-resources/src/main/resources/report-resources/images/driver-firefox.png b/serenity-report-resources/src/main/resources/report-resources/images/driver-firefox.png new file mode 100644 index 0000000000..fcfca19f6e Binary files /dev/null and b/serenity-report-resources/src/main/resources/report-resources/images/driver-firefox.png differ diff --git a/serenity-report-resources/src/main/resources/report-resources/images/driver-htmlunit.png b/serenity-report-resources/src/main/resources/report-resources/images/driver-htmlunit.png new file mode 100644 index 0000000000..307e591e59 Binary files /dev/null and b/serenity-report-resources/src/main/resources/report-resources/images/driver-htmlunit.png differ diff --git a/serenity-report-resources/src/main/resources/report-resources/images/driver-iexplorer.png b/serenity-report-resources/src/main/resources/report-resources/images/driver-iexplorer.png new file mode 100644 index 0000000000..9d41dea843 Binary files /dev/null and b/serenity-report-resources/src/main/resources/report-resources/images/driver-iexplorer.png differ diff --git a/serenity-report-resources/src/main/resources/report-resources/images/driver-opera.png b/serenity-report-resources/src/main/resources/report-resources/images/driver-opera.png new file mode 100644 index 0000000000..53ea4559c3 Binary files /dev/null and b/serenity-report-resources/src/main/resources/report-resources/images/driver-opera.png differ diff --git a/serenity-report-resources/src/main/resources/report-resources/images/driver-phantomjs.png b/serenity-report-resources/src/main/resources/report-resources/images/driver-phantomjs.png new file mode 100644 index 0000000000..295511c4e6 Binary files /dev/null and b/serenity-report-resources/src/main/resources/report-resources/images/driver-phantomjs.png differ diff --git a/serenity-report-resources/src/main/resources/report-resources/images/driver-provided.png b/serenity-report-resources/src/main/resources/report-resources/images/driver-provided.png new file mode 100644 index 0000000000..7e473d27f8 Binary files /dev/null and b/serenity-report-resources/src/main/resources/report-resources/images/driver-provided.png differ diff --git a/serenity-report-resources/src/main/resources/report-resources/images/driver-remote.png b/serenity-report-resources/src/main/resources/report-resources/images/driver-remote.png new file mode 100644 index 0000000000..d72515c816 Binary files /dev/null and b/serenity-report-resources/src/main/resources/report-resources/images/driver-remote.png differ diff --git a/serenity-report-resources/src/main/resources/report-resources/images/driver-safari.png b/serenity-report-resources/src/main/resources/report-resources/images/driver-safari.png new file mode 100644 index 0000000000..abbf228597 Binary files /dev/null and b/serenity-report-resources/src/main/resources/report-resources/images/driver-safari.png differ