diff --git a/CHANGELOG b/CHANGELOG index 186f3acd..22ad038e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,28 @@ +3.77.0 +====== +9 October 2024 +- Update Gwen core from v3.65.0 to v[3.66.0](https://github.com/gwen-interpreter/gwen/releases/tag/v3.66.0) + - Add `results` report format option for declarative CSV reporting + - Introduce `@Results` annotation to support logging CSV results at any node level + - Improved error report handling and reporting + - Add impicit variables: + - `gwen.feature.displayName` + - `gwen.feature.eval.started` + - `gwen.feature.eval.finished` + - `gwen.rule.eval.started` + - `gwen.rule.eval.finished` + - `gwen.scenario.displayName` + - `gwen.scenario.eval.started` + - `gwen.scenario.eval.finished` + - `gwen.stepDef.displayName` + - `gwen.stepDef.eval.started` + - `gwen.stepDef.eval.finished` + - `gwen.examples.name` + - `gwen.examples.eval.start.msecs` + - `gwen.examples.eval.started` + - `gwen.examples.eval.finished` + - `gwen.examples.eval.status.keyword` + 3.76.0 ====== 26 September 2024 diff --git a/build.sbt b/build.sbt index 27436b87..ac5df185 100644 --- a/build.sbt +++ b/build.sbt @@ -1,8 +1,8 @@ enablePlugins(GitVersioning) // gwen core & web versions -val gwenVersion = "3.65.0" -val gwenWebVersion = "3.76.0" +val gwenVersion = "3.66.0" +val gwenWebVersion = "3.77.0" git.baseVersion := gwenWebVersion git.useGitDescribe := true diff --git a/gwen.conf b/gwen.conf index d9cecd8c..7450a3e4 100644 --- a/gwen.conf +++ b/gwen.conf @@ -20,11 +20,169 @@ gwen { behavior { rules = "lenient" # strict|lenient } + cli { # CLI options + options { # See: https://gweninterpreter.org/docs/settings/reference#cli-settings + format = [ + "html" + "results" + # "junit" + # "json" + # "rp" + # "none" + ] + } + } feature { mode = "imperative" # declarative|imperative } - output { - dir = "target" + outDir = "target" + report { + results { + fields { + feature { + status = [ + { field = "EVAL_STATUS", ref = "gwen.feature.eval.status.keyword.upperCased" } + { field = "EVAL_STARTED", ref = "gwen.feature.eval.started" } + { field = "EVAL_FINISHED", ref = "gwen.feature.eval.finished" } + ] + details = [ + { field = "FEATURE_FILE", ref = "gwen.feature.file.path" } + { field = "FEATURE_NAME", ref = "gwen.feature.displayName" } + ] + duration = [ + { field = "EVAL_DURATION", ref = "gwen.feature.eval.duration" } + ] + message = [ + { field = "EVAL_MESSAGE", ref = "gwen.feature.eval.status.message" } + ] + } + scenario { + status = [ + { field = "EVAL_STATUS", ref = "gwen.scenario.eval.status.keyword.upperCased" } + { field = "EVAL_STARTED", ref = "gwen.scenario.eval.started" } + { field = "EVAL_FINISHED", ref = "gwen.scenario.eval.finished" } + ] + details = [ + ${gwen.report.results.fields.feature.details} + { field = "SCENARIO_NAME", ref = "gwen.scenario.displayName" } + ] + duration = [ + { field = "EVAL_DURATION", ref = "gwen.scenario.eval.duration" } + ] + message = [ + { field = "EVAL_MESSAGE", ref = "gwen.scenario.eval.status.message" } + ] + } + stepDef { + status = [ + { field = "EVAL_STATUS", ref = "gwen.stepDef.eval.status.keyword.upperCased" } + { field = "EVAL_STARTED", ref = "gwen.stepDef.eval.started" } + { field = "EVAL_FINISHED", ref = "gwen.stepDef.eval.finished" } + ] + details = [ + { field = "STEPDEF_NAME", ref = "gwen.stepDef.displayName" } + ] + duration = [ + { field = "EVAL_DURATION", ref = "gwen.stepDef.eval.duration" } + ] + message = [ + { field = "EVAL_MESSAGE", ref = "gwen.stepDef.eval.status.message" } + ] + } + input { + data = [ + { field = "*", ref = "$" } + ] + } + } + files { + feature { + passed { + file = "feature-results-PASSED.csv" + scope = "Feature" + status = "Passed" + fields = [ + ${gwen.report.results.fields.feature.status} + ${gwen.report.results.fields.feature.details} + ${gwen.report.results.fields.feature.duration} + ${gwen.report.results.fields.input.data} + ] + } + failed { + file = "feature-results-FAILED.csv" + scope = "Feature" + status = "Failed" + fields = [ + ${gwen.report.results.fields.feature.status} + ${gwen.report.results.fields.feature.details} + ${gwen.report.results.fields.feature.duration} + ${gwen.report.results.fields.input.data} + ${gwen.report.results.fields.feature.message} + ] + } + all { + file = "feature-results-ALL.csv" + scope = "Feature" + fields = [ + ${gwen.report.results.fields.feature.status} + ${gwen.report.results.fields.feature.details} + ${gwen.report.results.fields.feature.duration} + ${gwen.report.results.fields.input.data} + ${gwen.report.results.fields.feature.message} + ] + } + } + scenario { + passed { + file = "scenario-results-PASSED.csv" + scope = "Scenario" + status = "Passed" + fields = [ + ${gwen.report.results.fields.scenario.status} + ${gwen.report.results.fields.scenario.details} + ${gwen.report.results.fields.scenario.duration} + ${gwen.report.results.fields.input.data} + ] + } + failed { + file = "scenario-results-FAILED.csv" + scope = "Scenario" + status = "Failed" + fields = [ + ${gwen.report.results.fields.scenario.status} + ${gwen.report.results.fields.scenario.details} + ${gwen.report.results.fields.scenario.duration} + ${gwen.report.results.fields.input.data} + ${gwen.report.results.fields.scenario.message} + ] + } + all { + file = "scenario-results-ALL.csv" + scope = "Scenario" + fields = [ + ${gwen.report.results.fields.scenario.status} + ${gwen.report.results.fields.scenario.details} + ${gwen.report.results.fields.scenario.duration} + ${gwen.report.results.fields.input.data} + ${gwen.report.results.fields.scenario.message} + ] + } + } + stepDef { + all { + file = "stepDef-results-ALL.csv" + scope = "StepDef" + fields = [ + ${gwen.report.results.fields.stepDef.status} + ${gwen.report.results.fields.stepDef.details} + ${gwen.report.results.fields.stepDef.duration} + ${gwen.report.results.fields.input.data} + ${gwen.report.results.fields.stepDef.message} + ] + } + } + } + } } target { browser = "chrome" diff --git a/src/main/resources/gwen.conf b/src/main/resources/gwen.conf index b80c68e6..361f767d 100644 --- a/src/main/resources/gwen.conf +++ b/src/main/resources/gwen.conf @@ -29,7 +29,7 @@ gwen { } browser { headless = false - # size = "" # x, eg: 1200x800 + # size = "" # x eg: 1200x800 } capabilities { # name value pairs # name1 = "value1" @@ -38,13 +38,13 @@ gwen { } chrome { args = [ # value list - # "arg1", - # "arg2", + # "arg1" + # "arg2" # .. ] extensions = [ # value list of crx file paths - # "ext1", - # "ext2", + # "ext1" + # "ext2" # .. ] mobile { # name value pairs @@ -64,13 +64,13 @@ gwen { } edge { args = [ # value list - # "arg1", - # "arg2", + # "arg1" + # "arg2" # .. ] extensions = [ # value list of crx file paths - # "ext1", - # "ext2", + # "ext1" + # "ext2" # .. ] mobile { # name value pairs diff --git a/src/main/resources/init/gwen.conf b/src/main/resources/init/gwen.conf index 803bc5b3..b1fbf12a 100644 --- a/src/main/resources/init/gwen.conf +++ b/src/main/resources/init/gwen.conf @@ -58,9 +58,10 @@ gwen { batch = false format = [ "html" - # "junit", - # "json", - # "rp", + # "results" + # "junit" + # "json" + # "rp" # "none" ] dryRun = false @@ -73,8 +74,8 @@ gwen { parallel = false report = ${gwen.outDir}/reports tags = [ - # "@tag1", - # "~@tag2", + # "@tag1" + # "~@tag2" # .. ] verbose = false @@ -123,9 +124,6 @@ gwen { mask { char = "*" } - output { - dir = "${gwen.baseDir}/output" - } parallel { maxThreads = auto # auto|number (auto = all available cores) } @@ -139,6 +137,124 @@ gwen { functions = true } overwrite = false + results { + fields { + feature { + status = [ + { field = "EVAL_STATUS", ref = "gwen.feature.eval.status.keyword.upperCased" } + { field = "EVAL_STARTED", ref = "gwen.feature.eval.started" } + { field = "EVAL_FINISHED", ref = "gwen.feature.eval.finished" } + ] + details = [ + { field = "FEATURE_FILE", ref = "gwen.feature.file.path" } + { field = "FEATURE_NAME", ref = "gwen.feature.displayName" } + ] + duration = [ + { field = "EVAL_DURATION", ref = "gwen.feature.eval.duration" } + ] + message = [ + { field = "EVAL_MESSAGE", ref = "gwen.feature.eval.status.message" } + ] + } + scenario { + status = [ + { field = "EVAL_STATUS", ref = "gwen.scenario.eval.status.keyword.upperCased" } + { field = "EVAL_STARTED", ref = "gwen.scenario.eval.started" } + { field = "EVAL_FINISHED", ref = "gwen.scenario.eval.finished" } + ] + details = [ + ${gwen.report.results.fields.feature.details} + { field = "SCENARIO_NAME", ref = "gwen.scenario.displayName" } + ] + duration = [ + { field = "EVAL_DURATION", ref = "gwen.scenario.eval.duration" } + ] + message = [ + { field = "EVAL_MESSAGE", ref = "gwen.scenario.eval.status.message" } + ] + } + input { + data = [ + # Use this if input CSV file will always contain a header row (otherwise list fields explicitly here instead) + { field = "*", ref = "$" } + ] + } + } + files { + feature { + passed { + file = "feature-results-PASSED.csv" + scope = "Feature" + status = "Passed" + fields = [ + ${gwen.report.results.fields.feature.status} + ${gwen.report.results.fields.feature.details} + ${gwen.report.results.fields.feature.duration} + ${gwen.report.results.fields.input.data} + ] + } + failed { + file = "feature-results-FAILED.csv" + scope = "Feature" + status = "Failed" + fields = [ + ${gwen.report.results.fields.feature.status} + ${gwen.report.results.fields.feature.details} + ${gwen.report.results.fields.feature.duration} + ${gwen.report.results.fields.input.data} + ${gwen.report.results.fields.feature.message} + ] + } + all { + file = "feature-results-ALL.csv" + scope = "Feature" + fields = [ + ${gwen.report.results.fields.feature.status} + ${gwen.report.results.fields.feature.details} + ${gwen.report.results.fields.feature.duration} + ${gwen.report.results.fields.input.data} + ${gwen.report.results.fields.feature.message} + ] + } + } + scenario { + passed { + file = "scenario-results-PASSED.csv" + scope = "Scenario" + status = "Passed" + fields = [ + ${gwen.report.results.fields.scenario.status} + ${gwen.report.results.fields.scenario.details} + ${gwen.report.results.fields.scenario.duration} + ${gwen.report.results.fields.input.data} + ] + } + failed { + file = "scenario-results-FAILED.csv" + scope = "Scenario" + status = "Failed" + fields = [ + ${gwen.report.results.fields.scenario.status} + ${gwen.report.results.fields.scenario.details} + ${gwen.report.results.fields.scenario.duration} + ${gwen.report.results.fields.input.data} + ${gwen.report.results.fields.scenario.message} + ] + } + all { + file = "scenario-results-ALL.csv" + scope = "Scenario" + fields = [ + ${gwen.report.results.fields.scenario.status} + ${gwen.report.results.fields.scenario.details} + ${gwen.report.results.fields.scenario.duration} + ${gwen.report.results.fields.input.data} + ${gwen.report.results.fields.scenario.message} + ] + } + } + } + } slideshow { create = false framespersecond = 4 @@ -199,7 +315,7 @@ gwen { } browser { headless = false - # size = "" # x, eg: 1200x800 + # size = "" # x eg: 1200x800 } capture { screenshots { @@ -227,7 +343,7 @@ gwen { wait { seconds = ${gwen.web.wait.seconds} } - }, + } maximize = false remote { localFileDetector = auto # auto|true|false diff --git a/src/main/scala/gwen/web/eval/ImplicitWebValueKeys.scala b/src/main/scala/gwen/web/eval/ImplicitWebValueKeys.scala new file mode 100644 index 00000000..a543cff6 --- /dev/null +++ b/src/main/scala/gwen/web/eval/ImplicitWebValueKeys.scala @@ -0,0 +1,23 @@ +/* + * Copyright 2024 Branko Juric, Brady Wood + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package gwen.web.eval + +trait ImplicitWebValueKeys { + + val `gwen.web.sessionId` = "gwen.web.sessionId" + +} \ No newline at end of file diff --git a/src/main/scala/gwen/web/eval/WebContext.scala b/src/main/scala/gwen/web/eval/WebContext.scala index b9326741..b787014e 100644 --- a/src/main/scala/gwen/web/eval/WebContext.scala +++ b/src/main/scala/gwen/web/eval/WebContext.scala @@ -56,7 +56,7 @@ import java.io.File /** * The web evaluatioin context. */ -class WebContext(options: GwenOptions, envState: EnvState, driverManager: DriverManager) extends EvalContext(options, envState) with LazyLogging with WebSessionEventListener { +class WebContext(options: GwenOptions, envState: EnvState, driverManager: DriverManager) extends EvalContext(options, envState) with LazyLogging with WebSessionEventListener with ImplicitWebValueKeys { Try(logger.info(s"GWEN_CLASSPATH = ${sys.env("GWEN_CLASSPATH")}")) Try(logger.info(s"SELENIUM_HOME = ${sys.env("SELENIUM_HOME")}")) @@ -71,12 +71,12 @@ class WebContext(options: GwenOptions, envState: EnvState, driverManager: Driver if (WebSettings.videoEnabled) { addVideo(new File(GwenSettings.`gwen.video.dir`, s"$sessionId.mp4")) } - envState.scopes.topScope.set("gwen.web.sessionId", sessionId) + envState.scopes.topScope.set(`gwen.web.sessionId`, sessionId) } } override def sessionClosed(event: WebSessionEvent): Unit = { - envState.scopes.topScope.set("gwen.web.sessionId", null) + envState.scopes.topScope.set(`gwen.web.sessionId`, null) } def webElementlocator = new WebElementLocator(this) @@ -390,7 +390,7 @@ class WebContext(options: GwenOptions, envState: EnvState, driverManager: Driver */ def withWebDriver[T](function: WebDriver => T)(implicit takeScreenShot: Boolean = false): Option[T] = { evaluate { - topScope.set("gwen.web.sessionId", DryValueBinding.unresolved("gwen.web.sessionId")) + topScope.set(`gwen.web.sessionId`, DryValueBinding.unresolved(`gwen.web.sessionId`)) None.asInstanceOf[Option[T]] } { driverManager.withWebDriver { driver => diff --git a/src/main/scala/gwen/web/eval/lambda/composite/IfElementCondition.scala b/src/main/scala/gwen/web/eval/lambda/composite/IfElementCondition.scala index 344bbf67..4ce1c220 100644 --- a/src/main/scala/gwen/web/eval/lambda/composite/IfElementCondition.scala +++ b/src/main/scala/gwen/web/eval/lambda/composite/IfElementCondition.scala @@ -53,7 +53,7 @@ import scala.util.Failure val iStep = step.copy(withEvalStatus = Pending) val ifTag = Tag(Annotations.If) val tags = List(Tag(Annotations.Synthetic), ifTag, Tag(Annotations.StepDef)) - val iStepDef = Scenario(None, tags, ifTag.toString, cond, Nil, None, List(step.copy(withName = doStep)), Nil, Nil, Nil) + val iStepDef = Scenario(None, tags, ifTag.toString, cond, None, Nil, None, List(step.copy(withName = doStep)), Nil, Nil, Nil) val sdCall = () => engine.callStepDef(step, iStepDef, iStep, ctx) ctx.evaluate(sdCall()) { val satisfied = ctx.isElementState(binding, state, negate) diff --git a/src/test/features-data/Data.csv b/src/test/features-data/Data.csv index 4820cb04..ad670c4f 100644 --- a/src/test/features-data/Data.csv +++ b/src/test/features-data/Data.csv @@ -1,2 +1,3 @@ WEBSITE https://google.com.au?q=c1 +https://google.com.au?q=c2 diff --git a/src/test/scala/gwen/web/eval/WebSettingsTest.scala b/src/test/scala/gwen/web/eval/WebSettingsTest.scala index 18185b94..a178638b 100644 --- a/src/test/scala/gwen/web/eval/WebSettingsTest.scala +++ b/src/test/scala/gwen/web/eval/WebSettingsTest.scala @@ -20,17 +20,21 @@ import gwen.web._ import gwen.core.AssertionMode import gwen.core.CLISettings +import gwen.core.GwenOptions import gwen.core.GwenSettings import gwen.core.Settings import gwen.core.behavior.BehaviorMode import gwen.core.behavior.FeatureMode +import gwen.core.node.NodeType import gwen.core.report.ReportFormat import gwen.core.report.rp.RPConfig.ErrorBlocks import gwen.core.report.rp.RPConfig.ErrorReportingMode import gwen.core.report.rp.RPConfig.StepDefFormat import gwen.core.report.rp.RPConfig.TestCaseIdKeys import gwen.core.report.rp.RPSettings +import gwen.core.report.results.ResultField import gwen.core.state.StateLevel +import gwen.core.status.StatusKeyword import org.scalatest.matchers.should.Matchers import org.scalatestplus.mockito.MockitoSugar @@ -57,7 +61,7 @@ class WebSettingsTest extends BaseTest with Matchers with MockitoSugar { GwenSettings.`gwen.feature.mode` should be (FeatureMode.imperative) GwenSettings.`gwen.mask.char` should be ('*') GwenSettings.`gwen.baseDir`.getPath should be (".") - GwenSettings.`gwen.outDir`.getPath should be ("output") + GwenSettings.`gwen.outDir`.getPath should be ("target") GwenSettings.`gwen.parallel.maxThreads` should be (GwenSettings.availableProcessors) GwenSettings.`gwen.rampup.interval.seconds` should be (None) GwenSettings.`gwen.report.overwrite` should be (false) @@ -149,7 +153,7 @@ class WebSettingsTest extends BaseTest with Matchers with MockitoSugar { Settings.init( new File("src/main/resources/init/gwen.conf"), new File("src/main/resources/init/browsers/chrome.conf")) - assertInitConf(".", "output") + assertInitConf(".", "target") } } } @@ -160,7 +164,7 @@ class WebSettingsTest extends BaseTest with Matchers with MockitoSugar { Settings.init( new File("src/main/resources/init/gwen.conf"), new File("src/main/resources/init/browsers/chrome.conf")) - assertInitConf("gwen", "gwen/output") + assertInitConf("gwen", "target") } } } @@ -170,16 +174,16 @@ class WebSettingsTest extends BaseTest with Matchers with MockitoSugar { GwenSettings.`gwen.assertion.mode` should be (AssertionMode.hard) GwenSettings.`gwen.associative.meta` should be (true) GwenSettings.`gwen.auto.bind.tableData.outline.examples` should be (true) - GwenSettings.`gwen.auto.discover.data.csv` should be (false) + GwenSettings.`gwen.auto.discover.data.csv` should be (true) GwenSettings.`gwen.auto.discover.data.json` should be (false) GwenSettings.`gwen.auto.discover.meta` should be (true) GwenSettings.`gwen.auto.trim.data.csv` should be (false) GwenSettings.`gwen.auto.trim.data.json` should be (false) - GwenSettings.`gwen.behavior.rules` should be (BehaviorMode.strict) + GwenSettings.`gwen.behavior.rules` should be (BehaviorMode.lenient) GwenSettings.`gwen.feature.dialect` should be ("en") GwenSettings.`gwen.feature.failfast.enabled` should be (true) GwenSettings.`gwen.feature.failfast.exit` should be (false) - GwenSettings.`gwen.feature.mode` should be (FeatureMode.declarative) + GwenSettings.`gwen.feature.mode` should be (FeatureMode.imperative) GwenSettings.`gwen.mask.char` should be ('*') GwenSettings.`gwen.baseDir`.getPath should be (expectedBaseDir) GwenSettings.`gwen.outDir`.getPath should be (expectedOutDir) @@ -199,7 +203,7 @@ class WebSettingsTest extends BaseTest with Matchers with MockitoSugar { GwenSettings.`gwen.console.repl.tabCompletion` should be (true) GwenSettings.`gwen.logLevel.deprecations` should be (Level.WARNING) - CLISettings.`gwen.cli.options.format` should be (Nil) + CLISettings.`gwen.cli.options.format` should be (List(ReportFormat.html, ReportFormat.results)) RPSettings.`gwen.rp.debug` should be (false) RPSettings.`gwen.rp.heartbeat.enabled` should be (true) @@ -288,14 +292,14 @@ class WebSettingsTest extends BaseTest with Matchers with MockitoSugar { GwenSettings.`gwen.auto.discover.meta` should be (true) GwenSettings.`gwen.auto.trim.data.csv` should be (false) GwenSettings.`gwen.auto.trim.data.json` should be (false) - GwenSettings.`gwen.behavior.rules` should be (BehaviorMode.strict) + GwenSettings.`gwen.behavior.rules` should be (BehaviorMode.lenient) GwenSettings.`gwen.feature.dialect` should be ("en") GwenSettings.`gwen.feature.failfast.enabled` should be (true) GwenSettings.`gwen.feature.failfast.exit` should be (false) GwenSettings.`gwen.feature.mode` should be (FeatureMode.imperative) GwenSettings.`gwen.mask.char` should be ('*') GwenSettings.`gwen.baseDir`.getPath should be (".") - GwenSettings.`gwen.outDir`.getPath should be ("output") + GwenSettings.`gwen.outDir`.getPath should be ("target") GwenSettings.`gwen.parallel.maxThreads` should be (GwenSettings.availableProcessors) GwenSettings.`gwen.rampup.interval.seconds` should be (None) GwenSettings.`gwen.report.overwrite` should be (false) @@ -311,7 +315,7 @@ class WebSettingsTest extends BaseTest with Matchers with MockitoSugar { GwenSettings.`gwen.console.repl.autoSuggestions` should be (true) GwenSettings.`gwen.console.repl.tabCompletion` should be (true) GwenSettings.`gwen.logLevel.deprecations` should be (Level.WARNING) - + RPSettings.`gwen.rp.debug` should be (false) RPSettings.`gwen.rp.heartbeat.enabled` should be (true) RPSettings.`gwen.rp.heartbeat.timeoutSecs` should be (5) @@ -373,4 +377,113 @@ class WebSettingsTest extends BaseTest with Matchers with MockitoSugar { } + "Results files in gwen init conf" should "resolve" in { + Settings.exclusively { + withSetting("gwen.initDir", "gwen") { + Settings.init(new File("src/main/resources/init/gwen.conf")) + val resDir = "output/reports/results" + val resFiles = GwenSettings.`gwen.report.results.files`(GwenOptions()) + resFiles.size should be (7) + val fPassed = resFiles.find(_.id == "feature.passed").get + fPassed.id should be ("feature.passed") + fPassed.file should be (new File(s"$resDir/feature-results-PASSED.csv")) + fPassed.scope.map(_.nodeType) should be (Some(NodeType.Feature)) + fPassed.scope.flatMap(_.nodeName) should be (None) + fPassed.status should be (Some(StatusKeyword.Passed)) + fPassed.fields should be (List( + ResultField("EVAL_STATUS", "gwen.feature.eval.status.keyword.upperCased", false), + ResultField("EVAL_STARTED", "gwen.feature.eval.started", false), + ResultField("EVAL_FINISHED", "gwen.feature.eval.finished", false), + ResultField("FEATURE_FILE", "gwen.feature.file.path", false), + ResultField("FEATURE_NAME", "gwen.feature.displayName", false), + ResultField("EVAL_DURATION", "gwen.feature.eval.duration", false))) + val fFailed = resFiles.find(_.id == "feature.failed").get + fFailed.id should be ("feature.failed") + fFailed.file should be (new File(s"$resDir/feature-results-FAILED.csv")) + fFailed.scope.map(_.nodeType) should be (Some(NodeType.Feature)) + fFailed.scope.flatMap(_.nodeName) should be (None) + fFailed.status should be (Some(StatusKeyword.Failed)) + fFailed.fields should be (List( + ResultField("EVAL_STATUS", "gwen.feature.eval.status.keyword.upperCased", false), + ResultField("EVAL_STARTED", "gwen.feature.eval.started", false), + ResultField("EVAL_FINISHED", "gwen.feature.eval.finished", false), + ResultField("FEATURE_FILE", "gwen.feature.file.path", false), + ResultField("FEATURE_NAME", "gwen.feature.displayName", false), + ResultField("EVAL_DURATION", "gwen.feature.eval.duration", false), + ResultField("EVAL_MESSAGE", "gwen.feature.eval.status.message", false))) + val fAll = resFiles.find(_.id == "feature.all").get + fAll.id should be ("feature.all") + fAll.file should be (new File(s"$resDir/feature-results-ALL.csv")) + fAll.scope.map(_.nodeType) should be (Some(NodeType.Feature)) + fAll.scope.flatMap(_.nodeName) should be (None) + fAll.status should be (None) + fAll.fields should be (List( + ResultField("EVAL_STATUS", "gwen.feature.eval.status.keyword.upperCased", false), + ResultField("EVAL_STARTED", "gwen.feature.eval.started", false), + ResultField("EVAL_FINISHED", "gwen.feature.eval.finished", false), + ResultField("FEATURE_FILE", "gwen.feature.file.path", false), + ResultField("FEATURE_NAME", "gwen.feature.displayName", false), + ResultField("EVAL_DURATION", "gwen.feature.eval.duration", false), + ResultField("EVAL_MESSAGE", "gwen.feature.eval.status.message", false))) + val sPassed = resFiles.find(_.id == "scenario.passed").get + sPassed.id should be ("scenario.passed") + sPassed.file should be (new File(s"$resDir/scenario-results-PASSED.csv")) + sPassed.scope.map(_.nodeType) should be (Some(NodeType.Scenario)) + sPassed.scope.flatMap(_.nodeName) should be (None) + sPassed.status should be (Some(StatusKeyword.Passed)) + sPassed.fields should be (List( + ResultField("EVAL_STATUS", "gwen.scenario.eval.status.keyword.upperCased", false), + ResultField("EVAL_STARTED", "gwen.scenario.eval.started", false), + ResultField("EVAL_FINISHED", "gwen.scenario.eval.finished", false), + ResultField("FEATURE_FILE", "gwen.feature.file.path", false), + ResultField("FEATURE_NAME", "gwen.feature.displayName", false), + ResultField("SCENARIO_NAME", "gwen.scenario.displayName", false), + ResultField("EVAL_DURATION", "gwen.scenario.eval.duration", false))) + val sFailed = resFiles.find(_.id == "scenario.failed").get + sFailed.id should be ("scenario.failed") + sFailed.file should be (new File(s"$resDir/scenario-results-FAILED.csv")) + sFailed.scope.map(_.nodeType) should be (Some(NodeType.Scenario)) + sFailed.scope.flatMap(_.nodeName) should be (None) + sFailed.status should be (Some(StatusKeyword.Failed)) + sFailed.fields should be (List( + ResultField("EVAL_STATUS", "gwen.scenario.eval.status.keyword.upperCased", false), + ResultField("EVAL_STARTED", "gwen.scenario.eval.started", false), + ResultField("EVAL_FINISHED", "gwen.scenario.eval.finished", false), + ResultField("FEATURE_FILE", "gwen.feature.file.path", false), + ResultField("FEATURE_NAME", "gwen.feature.displayName", false), + ResultField("SCENARIO_NAME", "gwen.scenario.displayName", false), + ResultField("EVAL_DURATION", "gwen.scenario.eval.duration", false), + ResultField("EVAL_MESSAGE", "gwen.scenario.eval.status.message", false))) + val sAll = resFiles.find(_.id == "scenario.all").get + sAll.id should be ("scenario.all") + sAll.file should be (new File(s"$resDir/scenario-results-ALL.csv")) + sAll.scope.map(_.nodeType) should be (Some(NodeType.Scenario)) + sAll.scope.flatMap(_.nodeName) should be (None) + sAll.status should be (None) + sAll.fields should be (List( + ResultField("EVAL_STATUS", "gwen.scenario.eval.status.keyword.upperCased", false), + ResultField("EVAL_STARTED", "gwen.scenario.eval.started", false), + ResultField("EVAL_FINISHED", "gwen.scenario.eval.finished", false), + ResultField("FEATURE_FILE", "gwen.feature.file.path", false), + ResultField("FEATURE_NAME", "gwen.feature.displayName", false), + ResultField("SCENARIO_NAME", "gwen.scenario.displayName", false), + ResultField("EVAL_DURATION", "gwen.scenario.eval.duration", false), + ResultField("EVAL_MESSAGE", "gwen.scenario.eval.status.message", false))) + val sdAll = resFiles.find(_.id == "stepDef.all").get + sdAll.id should be ("stepDef.all") + sdAll.file should be (new File(s"$resDir/stepDef-results-ALL.csv")) + sdAll.scope.map(_.nodeType) should be (Some(NodeType.StepDef)) + sdAll.scope.flatMap(_.nodeName) should be (None) + sdAll.status should be (None) + sdAll.fields should be (List( + ResultField("EVAL_STATUS", "gwen.stepDef.eval.status.keyword.upperCased", false), + ResultField("EVAL_STARTED", "gwen.stepDef.eval.started", false), + ResultField("EVAL_FINISHED", "gwen.stepDef.eval.finished", false), + ResultField("STEPDEF_NAME", "gwen.stepDef.displayName", false), + ResultField("EVAL_DURATION", "gwen.stepDef.eval.duration", false), + ResultField("EVAL_MESSAGE", "gwen.stepDef.eval.status.message", false))) + } + } + } + } diff --git a/src/test/scala/gwen/web/features/BaseFeatureTest.scala b/src/test/scala/gwen/web/features/BaseFeatureTest.scala index 98115a88..9c01560f 100644 --- a/src/test/scala/gwen/web/features/BaseFeatureTest.scala +++ b/src/test/scala/gwen/web/features/BaseFeatureTest.scala @@ -32,7 +32,7 @@ abstract class BaseFeatureTest extends BaseTest { val reportPath = s"${this.getClass.getSimpleName}${if (dryRun) "-dryRun" else ""}" val execModePath = if (parallel) "parallel" else "sequential" val runRP = !dryRun && Settings.getOpt("rp").map(_.toBoolean).getOrElse(false) - var args = Array("-b", "-r", s"target/reports/$reportPath/$execModePath/$reportDir", "-f", s"junit,html,json${if (runRP) ",rp" else ""}") + var args = Array("-b", "-r", s"target/reports/$reportPath/$execModePath/$reportDir", "-f", s"html,results,junit,json${if (runRP) ",rp" else ""}") if (parallel) args = args ++ Array("--parallel") if (dryRun) args = args ++ Array("-n") if (dataFile.nonEmpty) args = args ++ Array("-i", dataFile.get)