|
1 | 1 | package io.cucumber.scalatest |
2 | 2 |
|
3 | | -import io.cucumber.core.options.{ |
4 | | - RuntimeOptionsBuilder, |
5 | | - CucumberOptionsAnnotationParser |
6 | | -} |
| 3 | +import io.cucumber.core.options.RuntimeOptionsBuilder |
7 | 4 | import io.cucumber.core.runtime.{Runtime => CucumberRuntime} |
8 | 5 | import org.scalatest.{Args, Status, Suite} |
9 | 6 |
|
10 | 7 | import scala.annotation.nowarn |
11 | 8 |
|
| 9 | +/** Configuration for Cucumber tests. |
| 10 | + * |
| 11 | + * @param features |
| 12 | + * paths to feature files or directories (e.g., "classpath:features") |
| 13 | + * @param glue |
| 14 | + * packages containing step definitions (e.g., "com.example.steps") |
| 15 | + * @param plugin |
| 16 | + * plugins to use (e.g., "pretty", "json:target/cucumber.json") |
| 17 | + */ |
| 18 | +case class CucumberOptions( |
| 19 | + features: List[String] = List.empty, |
| 20 | + glue: List[String] = List.empty, |
| 21 | + plugin: List[String] = List.empty |
| 22 | +) |
| 23 | + |
12 | 24 | /** A trait that allows Cucumber scenarios to be run with ScalaTest. |
13 | 25 | * |
14 | | - * Mix this trait into your test class and optionally annotate it with |
15 | | - * `@CucumberOptions` to configure the Cucumber runtime. |
| 26 | + * Mix this trait into your test class and define the `cucumberOptions` value |
| 27 | + * to configure the Cucumber runtime. |
16 | 28 | * |
17 | 29 | * Example: |
18 | 30 | * {{{ |
19 | | - * import io.cucumber.scalatest.CucumberSuite |
20 | | - * import io.cucumber.core.options.CucumberOptions |
| 31 | + * import io.cucumber.scalatest.{CucumberOptions, CucumberSuite} |
21 | 32 | * |
22 | | - * @CucumberOptions( |
23 | | - * features = Array("classpath:features"), |
24 | | - * glue = Array("com.example.stepdefinitions"), |
25 | | - * plugin = Array("pretty") |
26 | | - * ) |
27 | | - * class RunCucumberTest extends CucumberSuite |
| 33 | + * class RunCucumberTest extends CucumberSuite { |
| 34 | + * override val cucumberOptions = CucumberOptions( |
| 35 | + * features = List("classpath:features"), |
| 36 | + * glue = List("com.example.stepdefinitions"), |
| 37 | + * plugin = List("pretty") |
| 38 | + * ) |
| 39 | + * } |
28 | 40 | * }}} |
29 | 41 | */ |
30 | 42 | @nowarn |
31 | 43 | trait CucumberSuite extends Suite { |
32 | 44 |
|
| 45 | + /** Override this value to configure Cucumber options. If not overridden, |
| 46 | + * defaults will be used based on the package name. |
| 47 | + */ |
| 48 | + def cucumberOptions: CucumberOptions = CucumberOptions() |
| 49 | + |
33 | 50 | /** Runs the Cucumber scenarios. |
34 | 51 | * |
35 | 52 | * @param testName |
@@ -75,35 +92,34 @@ trait CucumberSuite extends Suite { |
75 | 92 | } |
76 | 93 |
|
77 | 94 | private def buildRuntimeOptions(): io.cucumber.core.options.RuntimeOptions = { |
78 | | - // Try the built-in annotation parser which works with various annotations |
79 | | - val annotationParser = new CucumberOptionsAnnotationParser() |
80 | 95 | val packageName = getClass.getPackage.getName |
81 | | - val featurePath = "classpath:" + packageName.replace('.', '/') |
82 | | - |
83 | | - try { |
84 | | - val annotationOptions = annotationParser.parse(getClass).build() |
85 | | - val options = new RuntimeOptionsBuilder().build(annotationOptions) |
86 | | - |
87 | | - // If no features were specified, use convention (classpath:package/name) |
88 | | - if (options.getFeaturePaths().isEmpty) { |
89 | | - val builder = new RuntimeOptionsBuilder() |
90 | | - builder.addFeature( |
91 | | - io.cucumber.core.feature.FeatureWithLines.parse(featurePath) |
92 | | - ) |
93 | | - builder.addGlue(java.net.URI.create("classpath:" + packageName)) |
94 | | - builder.build(annotationOptions) |
95 | | - } else { |
96 | | - options |
97 | | - } |
98 | | - } catch { |
99 | | - case _: Exception => |
100 | | - // If that fails, use convention based on package name |
101 | | - val builder = new RuntimeOptionsBuilder() |
102 | | - builder.addFeature( |
103 | | - io.cucumber.core.feature.FeatureWithLines.parse(featurePath) |
104 | | - ) |
105 | | - builder.addGlue(java.net.URI.create("classpath:" + packageName)) |
106 | | - builder.build() |
| 96 | + val builder = new RuntimeOptionsBuilder() |
| 97 | + |
| 98 | + // Add features |
| 99 | + val features = |
| 100 | + if (cucumberOptions.features.nonEmpty) cucumberOptions.features |
| 101 | + else List("classpath:" + packageName.replace('.', '/')) |
| 102 | + |
| 103 | + features.foreach { feature => |
| 104 | + builder.addFeature( |
| 105 | + io.cucumber.core.feature.FeatureWithLines.parse(feature) |
| 106 | + ) |
| 107 | + } |
| 108 | + |
| 109 | + // Add glue |
| 110 | + val glue = |
| 111 | + if (cucumberOptions.glue.nonEmpty) cucumberOptions.glue |
| 112 | + else List(packageName) |
| 113 | + |
| 114 | + glue.foreach { g => |
| 115 | + builder.addGlue(java.net.URI.create("classpath:" + g)) |
107 | 116 | } |
| 117 | + |
| 118 | + // Add plugins |
| 119 | + cucumberOptions.plugin.foreach { p => |
| 120 | + builder.addPluginName(p) |
| 121 | + } |
| 122 | + |
| 123 | + builder.build() |
108 | 124 | } |
109 | 125 | } |
0 commit comments